@midscene/web 0.3.2 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/es/debug.js +559 -0
- package/dist/es/index.js +3 -3
- package/dist/es/playwright.js +1245 -0
- package/dist/es/puppeteer.js +1049 -0
- package/dist/lib/debug.js +563 -0
- package/dist/lib/index.js +3 -3
- package/dist/lib/playwright.js +1245 -0
- package/dist/lib/puppeteer.js +1053 -0
- package/dist/types/debug.d.ts +17 -0
- package/dist/types/index.d.ts +11 -191
- package/dist/types/page.d-70ed000f.d.ts +6 -0
- package/dist/types/playwright.d.ts +36 -0
- package/dist/types/puppeteer.d.ts +33 -0
- package/dist/types/tasks-75eae15e.d.ts +125 -0
- package/package.json +26 -2
|
@@ -0,0 +1,1053 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __defProps = Object.defineProperties;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
7
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
8
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
9
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
10
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
11
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
12
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
13
|
+
var __spreadValues = (a, b) => {
|
|
14
|
+
for (var prop in b || (b = {}))
|
|
15
|
+
if (__hasOwnProp.call(b, prop))
|
|
16
|
+
__defNormalProp(a, prop, b[prop]);
|
|
17
|
+
if (__getOwnPropSymbols)
|
|
18
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
19
|
+
if (__propIsEnum.call(b, prop))
|
|
20
|
+
__defNormalProp(a, prop, b[prop]);
|
|
21
|
+
}
|
|
22
|
+
return a;
|
|
23
|
+
};
|
|
24
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
25
|
+
var __commonJS = (cb, mod) => function __require() {
|
|
26
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
27
|
+
};
|
|
28
|
+
var __export = (target, all) => {
|
|
29
|
+
for (var name in all)
|
|
30
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
31
|
+
};
|
|
32
|
+
var __copyProps = (to, from, except, desc) => {
|
|
33
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
34
|
+
for (let key of __getOwnPropNames(from))
|
|
35
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
36
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
37
|
+
}
|
|
38
|
+
return to;
|
|
39
|
+
};
|
|
40
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
41
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
42
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
43
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
44
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
45
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
46
|
+
mod
|
|
47
|
+
));
|
|
48
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
49
|
+
|
|
50
|
+
// ../../node_modules/.pnpm/dayjs@1.11.11/node_modules/dayjs/dayjs.min.js
|
|
51
|
+
var require_dayjs_min = __commonJS({
|
|
52
|
+
"../../node_modules/.pnpm/dayjs@1.11.11/node_modules/dayjs/dayjs.min.js"(exports, module2) {
|
|
53
|
+
"use strict";
|
|
54
|
+
!function(t, e) {
|
|
55
|
+
"object" == typeof exports && "undefined" != typeof module2 ? module2.exports = e() : "function" == typeof define && define.amd ? define(e) : (t = "undefined" != typeof globalThis ? globalThis : t || self).dayjs = e();
|
|
56
|
+
}(exports, function() {
|
|
57
|
+
"use strict";
|
|
58
|
+
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) {
|
|
59
|
+
var e2 = ["th", "st", "nd", "rd"], n2 = t2 % 100;
|
|
60
|
+
return "[" + t2 + (e2[(n2 - 20) % 10] || e2[n2] || e2[0]) + "]";
|
|
61
|
+
} }, m = function(t2, e2, n2) {
|
|
62
|
+
var r2 = String(t2);
|
|
63
|
+
return !r2 || r2.length >= e2 ? t2 : "" + Array(e2 + 1 - r2.length).join(n2) + t2;
|
|
64
|
+
}, v = { s: m, z: function(t2) {
|
|
65
|
+
var e2 = -t2.utcOffset(), n2 = Math.abs(e2), r2 = Math.floor(n2 / 60), i2 = n2 % 60;
|
|
66
|
+
return (e2 <= 0 ? "+" : "-") + m(r2, 2, "0") + ":" + m(i2, 2, "0");
|
|
67
|
+
}, m: function t2(e2, n2) {
|
|
68
|
+
if (e2.date() < n2.date())
|
|
69
|
+
return -t2(n2, e2);
|
|
70
|
+
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);
|
|
71
|
+
return +(-(r2 + (n2 - i2) / (s2 ? i2 - u2 : u2 - i2)) || 0);
|
|
72
|
+
}, a: function(t2) {
|
|
73
|
+
return t2 < 0 ? Math.ceil(t2) || 0 : Math.floor(t2);
|
|
74
|
+
}, p: function(t2) {
|
|
75
|
+
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$/, "");
|
|
76
|
+
}, u: function(t2) {
|
|
77
|
+
return void 0 === t2;
|
|
78
|
+
} }, g = "en", D = {};
|
|
79
|
+
D[g] = M;
|
|
80
|
+
var p = "$isDayjsObject", S = function(t2) {
|
|
81
|
+
return t2 instanceof _ || !(!t2 || !t2[p]);
|
|
82
|
+
}, w = function t2(e2, n2, r2) {
|
|
83
|
+
var i2;
|
|
84
|
+
if (!e2)
|
|
85
|
+
return g;
|
|
86
|
+
if ("string" == typeof e2) {
|
|
87
|
+
var s2 = e2.toLowerCase();
|
|
88
|
+
D[s2] && (i2 = s2), n2 && (D[s2] = n2, i2 = s2);
|
|
89
|
+
var u2 = e2.split("-");
|
|
90
|
+
if (!i2 && u2.length > 1)
|
|
91
|
+
return t2(u2[0]);
|
|
92
|
+
} else {
|
|
93
|
+
var a2 = e2.name;
|
|
94
|
+
D[a2] = e2, i2 = a2;
|
|
95
|
+
}
|
|
96
|
+
return !r2 && i2 && (g = i2), i2 || !r2 && g;
|
|
97
|
+
}, O = function(t2, e2) {
|
|
98
|
+
if (S(t2))
|
|
99
|
+
return t2.clone();
|
|
100
|
+
var n2 = "object" == typeof e2 ? e2 : {};
|
|
101
|
+
return n2.date = t2, n2.args = arguments, new _(n2);
|
|
102
|
+
}, b = v;
|
|
103
|
+
b.l = w, b.i = S, b.w = function(t2, e2) {
|
|
104
|
+
return O(t2, { locale: e2.$L, utc: e2.$u, x: e2.$x, $offset: e2.$offset });
|
|
105
|
+
};
|
|
106
|
+
var _ = function() {
|
|
107
|
+
function M2(t2) {
|
|
108
|
+
this.$L = w(t2.locale, null, true), this.parse(t2), this.$x = this.$x || t2.x || {}, this[p] = true;
|
|
109
|
+
}
|
|
110
|
+
var m2 = M2.prototype;
|
|
111
|
+
return m2.parse = function(t2) {
|
|
112
|
+
this.$d = function(t3) {
|
|
113
|
+
var e2 = t3.date, n2 = t3.utc;
|
|
114
|
+
if (null === e2)
|
|
115
|
+
return /* @__PURE__ */ new Date(NaN);
|
|
116
|
+
if (b.u(e2))
|
|
117
|
+
return /* @__PURE__ */ new Date();
|
|
118
|
+
if (e2 instanceof Date)
|
|
119
|
+
return new Date(e2);
|
|
120
|
+
if ("string" == typeof e2 && !/Z$/i.test(e2)) {
|
|
121
|
+
var r2 = e2.match($);
|
|
122
|
+
if (r2) {
|
|
123
|
+
var i2 = r2[2] - 1 || 0, s2 = (r2[7] || "0").substring(0, 3);
|
|
124
|
+
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);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return new Date(e2);
|
|
128
|
+
}(t2), this.init();
|
|
129
|
+
}, m2.init = function() {
|
|
130
|
+
var t2 = this.$d;
|
|
131
|
+
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();
|
|
132
|
+
}, m2.$utils = function() {
|
|
133
|
+
return b;
|
|
134
|
+
}, m2.isValid = function() {
|
|
135
|
+
return !(this.$d.toString() === l);
|
|
136
|
+
}, m2.isSame = function(t2, e2) {
|
|
137
|
+
var n2 = O(t2);
|
|
138
|
+
return this.startOf(e2) <= n2 && n2 <= this.endOf(e2);
|
|
139
|
+
}, m2.isAfter = function(t2, e2) {
|
|
140
|
+
return O(t2) < this.startOf(e2);
|
|
141
|
+
}, m2.isBefore = function(t2, e2) {
|
|
142
|
+
return this.endOf(e2) < O(t2);
|
|
143
|
+
}, m2.$g = function(t2, e2, n2) {
|
|
144
|
+
return b.u(t2) ? this[e2] : this.set(n2, t2);
|
|
145
|
+
}, m2.unix = function() {
|
|
146
|
+
return Math.floor(this.valueOf() / 1e3);
|
|
147
|
+
}, m2.valueOf = function() {
|
|
148
|
+
return this.$d.getTime();
|
|
149
|
+
}, m2.startOf = function(t2, e2) {
|
|
150
|
+
var n2 = this, r2 = !!b.u(e2) || e2, f2 = b.p(t2), l2 = function(t3, e3) {
|
|
151
|
+
var i2 = b.w(n2.$u ? Date.UTC(n2.$y, e3, t3) : new Date(n2.$y, e3, t3), n2);
|
|
152
|
+
return r2 ? i2 : i2.endOf(a);
|
|
153
|
+
}, $2 = function(t3, e3) {
|
|
154
|
+
return b.w(n2.toDate()[t3].apply(n2.toDate("s"), (r2 ? [0, 0, 0, 0] : [23, 59, 59, 999]).slice(e3)), n2);
|
|
155
|
+
}, y2 = this.$W, M3 = this.$M, m3 = this.$D, v2 = "set" + (this.$u ? "UTC" : "");
|
|
156
|
+
switch (f2) {
|
|
157
|
+
case h:
|
|
158
|
+
return r2 ? l2(1, 0) : l2(31, 11);
|
|
159
|
+
case c:
|
|
160
|
+
return r2 ? l2(1, M3) : l2(0, M3 + 1);
|
|
161
|
+
case o:
|
|
162
|
+
var g2 = this.$locale().weekStart || 0, D2 = (y2 < g2 ? y2 + 7 : y2) - g2;
|
|
163
|
+
return l2(r2 ? m3 - D2 : m3 + (6 - D2), M3);
|
|
164
|
+
case a:
|
|
165
|
+
case d:
|
|
166
|
+
return $2(v2 + "Hours", 0);
|
|
167
|
+
case u:
|
|
168
|
+
return $2(v2 + "Minutes", 1);
|
|
169
|
+
case s:
|
|
170
|
+
return $2(v2 + "Seconds", 2);
|
|
171
|
+
case i:
|
|
172
|
+
return $2(v2 + "Milliseconds", 3);
|
|
173
|
+
default:
|
|
174
|
+
return this.clone();
|
|
175
|
+
}
|
|
176
|
+
}, m2.endOf = function(t2) {
|
|
177
|
+
return this.startOf(t2, false);
|
|
178
|
+
}, m2.$set = function(t2, e2) {
|
|
179
|
+
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;
|
|
180
|
+
if (o2 === c || o2 === h) {
|
|
181
|
+
var y2 = this.clone().set(d, 1);
|
|
182
|
+
y2.$d[l2]($2), y2.init(), this.$d = y2.set(d, Math.min(this.$D, y2.daysInMonth())).$d;
|
|
183
|
+
} else
|
|
184
|
+
l2 && this.$d[l2]($2);
|
|
185
|
+
return this.init(), this;
|
|
186
|
+
}, m2.set = function(t2, e2) {
|
|
187
|
+
return this.clone().$set(t2, e2);
|
|
188
|
+
}, m2.get = function(t2) {
|
|
189
|
+
return this[b.p(t2)]();
|
|
190
|
+
}, m2.add = function(r2, f2) {
|
|
191
|
+
var d2, l2 = this;
|
|
192
|
+
r2 = Number(r2);
|
|
193
|
+
var $2 = b.p(f2), y2 = function(t2) {
|
|
194
|
+
var e2 = O(l2);
|
|
195
|
+
return b.w(e2.date(e2.date() + Math.round(t2 * r2)), l2);
|
|
196
|
+
};
|
|
197
|
+
if ($2 === c)
|
|
198
|
+
return this.set(c, this.$M + r2);
|
|
199
|
+
if ($2 === h)
|
|
200
|
+
return this.set(h, this.$y + r2);
|
|
201
|
+
if ($2 === a)
|
|
202
|
+
return y2(1);
|
|
203
|
+
if ($2 === o)
|
|
204
|
+
return y2(7);
|
|
205
|
+
var M3 = (d2 = {}, d2[s] = e, d2[u] = n, d2[i] = t, d2)[$2] || 1, m3 = this.$d.getTime() + r2 * M3;
|
|
206
|
+
return b.w(m3, this);
|
|
207
|
+
}, m2.subtract = function(t2, e2) {
|
|
208
|
+
return this.add(-1 * t2, e2);
|
|
209
|
+
}, m2.format = function(t2) {
|
|
210
|
+
var e2 = this, n2 = this.$locale();
|
|
211
|
+
if (!this.isValid())
|
|
212
|
+
return n2.invalidDate || l;
|
|
213
|
+
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) {
|
|
214
|
+
return t3 && (t3[n3] || t3(e2, r2)) || i3[n3].slice(0, s3);
|
|
215
|
+
}, d2 = function(t3) {
|
|
216
|
+
return b.s(s2 % 12 || 12, t3, "0");
|
|
217
|
+
}, $2 = f2 || function(t3, e3, n3) {
|
|
218
|
+
var r3 = t3 < 12 ? "AM" : "PM";
|
|
219
|
+
return n3 ? r3.toLowerCase() : r3;
|
|
220
|
+
};
|
|
221
|
+
return r2.replace(y, function(t3, r3) {
|
|
222
|
+
return r3 || function(t4) {
|
|
223
|
+
switch (t4) {
|
|
224
|
+
case "YY":
|
|
225
|
+
return String(e2.$y).slice(-2);
|
|
226
|
+
case "YYYY":
|
|
227
|
+
return b.s(e2.$y, 4, "0");
|
|
228
|
+
case "M":
|
|
229
|
+
return a2 + 1;
|
|
230
|
+
case "MM":
|
|
231
|
+
return b.s(a2 + 1, 2, "0");
|
|
232
|
+
case "MMM":
|
|
233
|
+
return h2(n2.monthsShort, a2, c2, 3);
|
|
234
|
+
case "MMMM":
|
|
235
|
+
return h2(c2, a2);
|
|
236
|
+
case "D":
|
|
237
|
+
return e2.$D;
|
|
238
|
+
case "DD":
|
|
239
|
+
return b.s(e2.$D, 2, "0");
|
|
240
|
+
case "d":
|
|
241
|
+
return String(e2.$W);
|
|
242
|
+
case "dd":
|
|
243
|
+
return h2(n2.weekdaysMin, e2.$W, o2, 2);
|
|
244
|
+
case "ddd":
|
|
245
|
+
return h2(n2.weekdaysShort, e2.$W, o2, 3);
|
|
246
|
+
case "dddd":
|
|
247
|
+
return o2[e2.$W];
|
|
248
|
+
case "H":
|
|
249
|
+
return String(s2);
|
|
250
|
+
case "HH":
|
|
251
|
+
return b.s(s2, 2, "0");
|
|
252
|
+
case "h":
|
|
253
|
+
return d2(1);
|
|
254
|
+
case "hh":
|
|
255
|
+
return d2(2);
|
|
256
|
+
case "a":
|
|
257
|
+
return $2(s2, u2, true);
|
|
258
|
+
case "A":
|
|
259
|
+
return $2(s2, u2, false);
|
|
260
|
+
case "m":
|
|
261
|
+
return String(u2);
|
|
262
|
+
case "mm":
|
|
263
|
+
return b.s(u2, 2, "0");
|
|
264
|
+
case "s":
|
|
265
|
+
return String(e2.$s);
|
|
266
|
+
case "ss":
|
|
267
|
+
return b.s(e2.$s, 2, "0");
|
|
268
|
+
case "SSS":
|
|
269
|
+
return b.s(e2.$ms, 3, "0");
|
|
270
|
+
case "Z":
|
|
271
|
+
return i2;
|
|
272
|
+
}
|
|
273
|
+
return null;
|
|
274
|
+
}(t3) || i2.replace(":", "");
|
|
275
|
+
});
|
|
276
|
+
}, m2.utcOffset = function() {
|
|
277
|
+
return 15 * -Math.round(this.$d.getTimezoneOffset() / 15);
|
|
278
|
+
}, m2.diff = function(r2, d2, l2) {
|
|
279
|
+
var $2, y2 = this, M3 = b.p(d2), m3 = O(r2), v2 = (m3.utcOffset() - this.utcOffset()) * e, g2 = this - m3, D2 = function() {
|
|
280
|
+
return b.m(y2, m3);
|
|
281
|
+
};
|
|
282
|
+
switch (M3) {
|
|
283
|
+
case h:
|
|
284
|
+
$2 = D2() / 12;
|
|
285
|
+
break;
|
|
286
|
+
case c:
|
|
287
|
+
$2 = D2();
|
|
288
|
+
break;
|
|
289
|
+
case f:
|
|
290
|
+
$2 = D2() / 3;
|
|
291
|
+
break;
|
|
292
|
+
case o:
|
|
293
|
+
$2 = (g2 - v2) / 6048e5;
|
|
294
|
+
break;
|
|
295
|
+
case a:
|
|
296
|
+
$2 = (g2 - v2) / 864e5;
|
|
297
|
+
break;
|
|
298
|
+
case u:
|
|
299
|
+
$2 = g2 / n;
|
|
300
|
+
break;
|
|
301
|
+
case s:
|
|
302
|
+
$2 = g2 / e;
|
|
303
|
+
break;
|
|
304
|
+
case i:
|
|
305
|
+
$2 = g2 / t;
|
|
306
|
+
break;
|
|
307
|
+
default:
|
|
308
|
+
$2 = g2;
|
|
309
|
+
}
|
|
310
|
+
return l2 ? $2 : b.a($2);
|
|
311
|
+
}, m2.daysInMonth = function() {
|
|
312
|
+
return this.endOf(c).$D;
|
|
313
|
+
}, m2.$locale = function() {
|
|
314
|
+
return D[this.$L];
|
|
315
|
+
}, m2.locale = function(t2, e2) {
|
|
316
|
+
if (!t2)
|
|
317
|
+
return this.$L;
|
|
318
|
+
var n2 = this.clone(), r2 = w(t2, e2, true);
|
|
319
|
+
return r2 && (n2.$L = r2), n2;
|
|
320
|
+
}, m2.clone = function() {
|
|
321
|
+
return b.w(this.$d, this);
|
|
322
|
+
}, m2.toDate = function() {
|
|
323
|
+
return new Date(this.valueOf());
|
|
324
|
+
}, m2.toJSON = function() {
|
|
325
|
+
return this.isValid() ? this.toISOString() : null;
|
|
326
|
+
}, m2.toISOString = function() {
|
|
327
|
+
return this.$d.toISOString();
|
|
328
|
+
}, m2.toString = function() {
|
|
329
|
+
return this.$d.toUTCString();
|
|
330
|
+
}, M2;
|
|
331
|
+
}(), k = _.prototype;
|
|
332
|
+
return O.prototype = k, [["$ms", r], ["$s", i], ["$m", s], ["$H", u], ["$W", a], ["$M", c], ["$y", h], ["$D", d]].forEach(function(t2) {
|
|
333
|
+
k[t2[1]] = function(e2) {
|
|
334
|
+
return this.$g(e2, t2[0], t2[1]);
|
|
335
|
+
};
|
|
336
|
+
}), O.extend = function(t2, e2) {
|
|
337
|
+
return t2.$i || (t2(e2, _, O), t2.$i = true), O;
|
|
338
|
+
}, O.locale = w, O.isDayjs = S, O.unix = function(t2) {
|
|
339
|
+
return O(1e3 * t2);
|
|
340
|
+
}, O.en = D[g], O.Ls = D, O.p = {}, O;
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
// src/puppeteer/index.ts
|
|
346
|
+
var puppeteer_exports = {};
|
|
347
|
+
__export(puppeteer_exports, {
|
|
348
|
+
PuppeteerAgent: () => PageAgent
|
|
349
|
+
});
|
|
350
|
+
module.exports = __toCommonJS(puppeteer_exports);
|
|
351
|
+
|
|
352
|
+
// src/common/agent.ts
|
|
353
|
+
var import_utils4 = require("@midscene/core/utils");
|
|
354
|
+
|
|
355
|
+
// src/common/tasks.ts
|
|
356
|
+
var import_node_assert2 = __toESM(require("assert"));
|
|
357
|
+
var import_core = __toESM(require("@midscene/core"));
|
|
358
|
+
var import_image2 = require("@midscene/core/image");
|
|
359
|
+
var import_utils2 = require("@midscene/core/utils");
|
|
360
|
+
|
|
361
|
+
// src/common/task-cache.ts
|
|
362
|
+
var TaskCache = class {
|
|
363
|
+
constructor(opts) {
|
|
364
|
+
this.cache = opts == null ? void 0 : opts.cache;
|
|
365
|
+
this.newCache = {
|
|
366
|
+
aiTasks: []
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
readCache(pageContext, type, userPrompt) {
|
|
370
|
+
var _a;
|
|
371
|
+
if (this.cache) {
|
|
372
|
+
const { aiTasks } = this.cache;
|
|
373
|
+
const index = aiTasks.findIndex((item) => item.prompt === userPrompt);
|
|
374
|
+
if (index === -1) {
|
|
375
|
+
return false;
|
|
376
|
+
}
|
|
377
|
+
const taskRes = aiTasks.splice(index, 1)[0];
|
|
378
|
+
if ((taskRes == null ? void 0 : taskRes.type) === "locate" && !((_a = taskRes.response) == null ? void 0 : _a.elements.every((element) => {
|
|
379
|
+
const findIndex = pageContext.content.findIndex(
|
|
380
|
+
(contentElement) => contentElement.id === element.id
|
|
381
|
+
);
|
|
382
|
+
if (findIndex === -1) {
|
|
383
|
+
return false;
|
|
384
|
+
}
|
|
385
|
+
return true;
|
|
386
|
+
}))) {
|
|
387
|
+
return false;
|
|
388
|
+
}
|
|
389
|
+
if (taskRes && taskRes.type === type && taskRes.prompt === userPrompt && this.pageContextEqual(taskRes.pageContext, pageContext)) {
|
|
390
|
+
return taskRes.response;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
return false;
|
|
394
|
+
}
|
|
395
|
+
saveCache(cache) {
|
|
396
|
+
var _a;
|
|
397
|
+
if (cache) {
|
|
398
|
+
(_a = this.newCache) == null ? void 0 : _a.aiTasks.push(cache);
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
pageContextEqual(taskPageContext, pageContext) {
|
|
402
|
+
return taskPageContext.size.width === pageContext.size.width && taskPageContext.size.height === pageContext.size.height;
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* Generate task cache data.
|
|
406
|
+
* This method is mainly used to create or obtain some cached data for tasks, and it returns a new cache object.
|
|
407
|
+
* In the cache object, it may contain task-related information, states, or other necessary data.
|
|
408
|
+
* 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.
|
|
409
|
+
* @returns {Object} Returns a new cache object, which may include task cache data.
|
|
410
|
+
*/
|
|
411
|
+
generateTaskCache() {
|
|
412
|
+
return this.newCache;
|
|
413
|
+
}
|
|
414
|
+
};
|
|
415
|
+
|
|
416
|
+
// src/common/utils.ts
|
|
417
|
+
var import_node_assert = __toESM(require("assert"));
|
|
418
|
+
var import_node_fs = __toESM(require("fs"));
|
|
419
|
+
var import_node_path = __toESM(require("path"));
|
|
420
|
+
var import_image = require("@midscene/core/image");
|
|
421
|
+
var import_utils = require("@midscene/core/utils");
|
|
422
|
+
var import_dayjs = __toESM(require_dayjs_min());
|
|
423
|
+
|
|
424
|
+
// src/web-element.ts
|
|
425
|
+
var WebElementInfo = class {
|
|
426
|
+
constructor({
|
|
427
|
+
content,
|
|
428
|
+
rect,
|
|
429
|
+
page,
|
|
430
|
+
locator,
|
|
431
|
+
id,
|
|
432
|
+
attributes
|
|
433
|
+
}) {
|
|
434
|
+
this.content = content;
|
|
435
|
+
this.rect = rect;
|
|
436
|
+
this.center = [
|
|
437
|
+
Math.floor(rect.left + rect.width / 2),
|
|
438
|
+
Math.floor(rect.top + rect.height / 2)
|
|
439
|
+
];
|
|
440
|
+
this.page = page;
|
|
441
|
+
this.locator = locator;
|
|
442
|
+
this.id = id;
|
|
443
|
+
this.attributes = attributes;
|
|
444
|
+
}
|
|
445
|
+
};
|
|
446
|
+
|
|
447
|
+
// src/common/utils.ts
|
|
448
|
+
async function parseContextFromWebPage(page, _opt) {
|
|
449
|
+
(0, import_node_assert.default)(page, "page is required");
|
|
450
|
+
const url = page.url();
|
|
451
|
+
const file = (0, import_utils.getTmpFile)("jpeg");
|
|
452
|
+
await page.screenshot({ path: file, type: "jpeg", quality: 75 });
|
|
453
|
+
const screenshotBuffer = (0, import_node_fs.readFileSync)(file);
|
|
454
|
+
const screenshotBase64 = (0, import_image.base64Encoded)(file);
|
|
455
|
+
const captureElementSnapshot = await getElementInfosFromPage(page);
|
|
456
|
+
const elementsInfo = await alignElements(
|
|
457
|
+
screenshotBuffer,
|
|
458
|
+
captureElementSnapshot,
|
|
459
|
+
page
|
|
460
|
+
);
|
|
461
|
+
const size = await (0, import_image.imageInfoOfBase64)(screenshotBase64);
|
|
462
|
+
return {
|
|
463
|
+
content: elementsInfo,
|
|
464
|
+
size,
|
|
465
|
+
screenshotBase64,
|
|
466
|
+
url
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
async function getElementInfosFromPage(page) {
|
|
470
|
+
const pathDir = findNearestPackageJson(__dirname);
|
|
471
|
+
(0, import_node_assert.default)(pathDir, `can't find pathDir, with ${__dirname}`);
|
|
472
|
+
const scriptPath = import_node_path.default.join(pathDir, "./dist/script/htmlElement.js");
|
|
473
|
+
const elementInfosScriptContent = (0, import_node_fs.readFileSync)(scriptPath, "utf-8");
|
|
474
|
+
const extraReturnLogic = `${elementInfosScriptContent}midscene_element_inspector.extractTextWithPosition()`;
|
|
475
|
+
const captureElementSnapshot = await page.evaluate(extraReturnLogic);
|
|
476
|
+
return captureElementSnapshot;
|
|
477
|
+
}
|
|
478
|
+
var sizeThreshold = 3;
|
|
479
|
+
async function alignElements(screenshotBuffer, elements, page) {
|
|
480
|
+
const textsAligned = [];
|
|
481
|
+
const validElements = elements.filter((item) => {
|
|
482
|
+
return item.rect.height >= sizeThreshold && item.rect.width >= sizeThreshold;
|
|
483
|
+
});
|
|
484
|
+
for (const item of validElements) {
|
|
485
|
+
const { rect, id, content, attributes, locator } = item;
|
|
486
|
+
textsAligned.push(
|
|
487
|
+
new WebElementInfo({
|
|
488
|
+
rect,
|
|
489
|
+
locator,
|
|
490
|
+
id,
|
|
491
|
+
content,
|
|
492
|
+
attributes,
|
|
493
|
+
page
|
|
494
|
+
})
|
|
495
|
+
);
|
|
496
|
+
}
|
|
497
|
+
return textsAligned;
|
|
498
|
+
}
|
|
499
|
+
function findNearestPackageJson(dir) {
|
|
500
|
+
const packageJsonPath = import_node_path.default.join(dir, "package.json");
|
|
501
|
+
if (import_node_fs.default.existsSync(packageJsonPath)) {
|
|
502
|
+
return dir;
|
|
503
|
+
}
|
|
504
|
+
const parentDir = import_node_path.default.dirname(dir);
|
|
505
|
+
if (parentDir === dir) {
|
|
506
|
+
return null;
|
|
507
|
+
}
|
|
508
|
+
return findNearestPackageJson(parentDir);
|
|
509
|
+
}
|
|
510
|
+
function reportFileName(tag = "web") {
|
|
511
|
+
const dateTimeInFileName = (0, import_dayjs.default)().format("YYYY-MM-DD_HH-mm-ss-SSS");
|
|
512
|
+
return `${tag}-${dateTimeInFileName}`;
|
|
513
|
+
}
|
|
514
|
+
function printReportMsg(filepath) {
|
|
515
|
+
console.log("Midscene - report file updated:", filepath);
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
// src/common/tasks.ts
|
|
519
|
+
var PageTaskExecutor = class {
|
|
520
|
+
constructor(page, opts) {
|
|
521
|
+
this.page = page;
|
|
522
|
+
this.insight = new import_core.default(async () => {
|
|
523
|
+
return await parseContextFromWebPage(page);
|
|
524
|
+
});
|
|
525
|
+
this.taskCache = new TaskCache(opts);
|
|
526
|
+
}
|
|
527
|
+
async recordScreenshot(timing) {
|
|
528
|
+
const file = (0, import_utils2.getTmpFile)("jpeg");
|
|
529
|
+
await this.page.screenshot(__spreadProps(__spreadValues({}, import_utils2.commonScreenshotParam), {
|
|
530
|
+
path: file
|
|
531
|
+
}));
|
|
532
|
+
const item = {
|
|
533
|
+
type: "screenshot",
|
|
534
|
+
ts: Date.now(),
|
|
535
|
+
screenshot: (0, import_image2.base64Encoded)(file),
|
|
536
|
+
timing
|
|
537
|
+
};
|
|
538
|
+
return item;
|
|
539
|
+
}
|
|
540
|
+
wrapExecutorWithScreenshot(taskApply) {
|
|
541
|
+
const taskWithScreenshot = __spreadProps(__spreadValues({}, taskApply), {
|
|
542
|
+
executor: async (param, context, ...args) => {
|
|
543
|
+
const recorder = [];
|
|
544
|
+
const { task } = context;
|
|
545
|
+
task.recorder = recorder;
|
|
546
|
+
const shot = await this.recordScreenshot(`before ${task.type}`);
|
|
547
|
+
recorder.push(shot);
|
|
548
|
+
const result = await taskApply.executor(param, context, ...args);
|
|
549
|
+
if (taskApply.type === "Action") {
|
|
550
|
+
await (0, import_utils2.sleep)(1e3);
|
|
551
|
+
const shot2 = await this.recordScreenshot("after Action");
|
|
552
|
+
recorder.push(shot2);
|
|
553
|
+
}
|
|
554
|
+
return result;
|
|
555
|
+
}
|
|
556
|
+
});
|
|
557
|
+
return taskWithScreenshot;
|
|
558
|
+
}
|
|
559
|
+
async convertPlanToExecutable(plans) {
|
|
560
|
+
const tasks = plans.map((plan2) => {
|
|
561
|
+
if (plan2.type === "Locate") {
|
|
562
|
+
const taskFind = {
|
|
563
|
+
type: "Insight",
|
|
564
|
+
subType: "Locate",
|
|
565
|
+
param: plan2.param,
|
|
566
|
+
executor: async (param) => {
|
|
567
|
+
let insightDump;
|
|
568
|
+
const dumpCollector = (dump) => {
|
|
569
|
+
insightDump = dump;
|
|
570
|
+
};
|
|
571
|
+
this.insight.onceDumpUpdatedFn = dumpCollector;
|
|
572
|
+
const pageContext = await this.insight.contextRetrieverFn();
|
|
573
|
+
const locateCache = this.taskCache.readCache(
|
|
574
|
+
pageContext,
|
|
575
|
+
"locate",
|
|
576
|
+
param.prompt
|
|
577
|
+
);
|
|
578
|
+
let locateResult;
|
|
579
|
+
const callAI = this.insight.aiVendorFn;
|
|
580
|
+
const element = await this.insight.locate(param.prompt, {
|
|
581
|
+
callAI: async (...message) => {
|
|
582
|
+
if (locateCache) {
|
|
583
|
+
locateResult = locateCache;
|
|
584
|
+
return Promise.resolve(locateCache);
|
|
585
|
+
}
|
|
586
|
+
locateResult = await callAI(...message);
|
|
587
|
+
(0, import_node_assert2.default)(locateResult);
|
|
588
|
+
return locateResult;
|
|
589
|
+
}
|
|
590
|
+
});
|
|
591
|
+
(0, import_node_assert2.default)(element, `Element not found: ${param.prompt}`);
|
|
592
|
+
if (locateResult) {
|
|
593
|
+
this.taskCache.saveCache({
|
|
594
|
+
type: "locate",
|
|
595
|
+
pageContext: {
|
|
596
|
+
url: pageContext.url,
|
|
597
|
+
size: pageContext.size
|
|
598
|
+
},
|
|
599
|
+
prompt: param.prompt,
|
|
600
|
+
response: locateResult
|
|
601
|
+
});
|
|
602
|
+
}
|
|
603
|
+
return {
|
|
604
|
+
output: {
|
|
605
|
+
element
|
|
606
|
+
},
|
|
607
|
+
log: {
|
|
608
|
+
dump: insightDump
|
|
609
|
+
},
|
|
610
|
+
cache: {
|
|
611
|
+
hit: Boolean(locateResult)
|
|
612
|
+
}
|
|
613
|
+
};
|
|
614
|
+
}
|
|
615
|
+
};
|
|
616
|
+
return taskFind;
|
|
617
|
+
}
|
|
618
|
+
if (plan2.type === "Assert" || plan2.type === "AssertWithoutThrow") {
|
|
619
|
+
const assertPlan = plan2;
|
|
620
|
+
const taskAssert = {
|
|
621
|
+
type: "Insight",
|
|
622
|
+
subType: "Assert",
|
|
623
|
+
param: assertPlan.param,
|
|
624
|
+
executor: async (param, taskContext) => {
|
|
625
|
+
const { task } = taskContext;
|
|
626
|
+
let insightDump;
|
|
627
|
+
const dumpCollector = (dump) => {
|
|
628
|
+
insightDump = dump;
|
|
629
|
+
};
|
|
630
|
+
this.insight.onceDumpUpdatedFn = dumpCollector;
|
|
631
|
+
const assertion = await this.insight.assert(
|
|
632
|
+
assertPlan.param.assertion
|
|
633
|
+
);
|
|
634
|
+
if (!assertion.pass) {
|
|
635
|
+
if (plan2.type === "Assert") {
|
|
636
|
+
task.output = assertion;
|
|
637
|
+
task.log = {
|
|
638
|
+
dump: insightDump
|
|
639
|
+
};
|
|
640
|
+
throw new Error(
|
|
641
|
+
assertion.thought || "Assertion failed without reason"
|
|
642
|
+
);
|
|
643
|
+
}
|
|
644
|
+
task.error = assertion.thought;
|
|
645
|
+
}
|
|
646
|
+
return {
|
|
647
|
+
output: assertion,
|
|
648
|
+
log: {
|
|
649
|
+
dump: insightDump
|
|
650
|
+
}
|
|
651
|
+
};
|
|
652
|
+
}
|
|
653
|
+
};
|
|
654
|
+
return taskAssert;
|
|
655
|
+
}
|
|
656
|
+
if (plan2.type === "Input") {
|
|
657
|
+
const taskActionInput = {
|
|
658
|
+
type: "Action",
|
|
659
|
+
subType: "Input",
|
|
660
|
+
param: plan2.param,
|
|
661
|
+
executor: async (taskParam, { element }) => {
|
|
662
|
+
if (element) {
|
|
663
|
+
await this.page.mouse.click(
|
|
664
|
+
element.center[0],
|
|
665
|
+
element.center[1]
|
|
666
|
+
);
|
|
667
|
+
}
|
|
668
|
+
(0, import_node_assert2.default)(taskParam.value, "No value to input");
|
|
669
|
+
await this.page.keyboard.type(taskParam.value);
|
|
670
|
+
}
|
|
671
|
+
};
|
|
672
|
+
return taskActionInput;
|
|
673
|
+
}
|
|
674
|
+
if (plan2.type === "KeyboardPress") {
|
|
675
|
+
const taskActionKeyboardPress = {
|
|
676
|
+
type: "Action",
|
|
677
|
+
subType: "KeyboardPress",
|
|
678
|
+
param: plan2.param,
|
|
679
|
+
executor: async (taskParam) => {
|
|
680
|
+
(0, import_node_assert2.default)(taskParam.value, "No key to press");
|
|
681
|
+
await this.page.keyboard.press(taskParam.value);
|
|
682
|
+
}
|
|
683
|
+
};
|
|
684
|
+
return taskActionKeyboardPress;
|
|
685
|
+
}
|
|
686
|
+
if (plan2.type === "Tap") {
|
|
687
|
+
const taskActionTap = {
|
|
688
|
+
type: "Action",
|
|
689
|
+
subType: "Tap",
|
|
690
|
+
executor: async (param, { element }) => {
|
|
691
|
+
(0, import_node_assert2.default)(element, "Element not found, cannot tap");
|
|
692
|
+
await this.page.mouse.click(
|
|
693
|
+
element.center[0],
|
|
694
|
+
element.center[1]
|
|
695
|
+
);
|
|
696
|
+
}
|
|
697
|
+
};
|
|
698
|
+
return taskActionTap;
|
|
699
|
+
}
|
|
700
|
+
if (plan2.type === "Hover") {
|
|
701
|
+
const taskActionHover = {
|
|
702
|
+
type: "Action",
|
|
703
|
+
subType: "Hover",
|
|
704
|
+
executor: async (param, { element }) => {
|
|
705
|
+
(0, import_node_assert2.default)(element, "Element not found, cannot hover");
|
|
706
|
+
await this.page.mouse.move(
|
|
707
|
+
element.center[0],
|
|
708
|
+
element.center[1]
|
|
709
|
+
);
|
|
710
|
+
}
|
|
711
|
+
};
|
|
712
|
+
return taskActionHover;
|
|
713
|
+
}
|
|
714
|
+
if (plan2.type === "Scroll") {
|
|
715
|
+
const taskActionScroll = {
|
|
716
|
+
type: "Action",
|
|
717
|
+
subType: "Scroll",
|
|
718
|
+
param: plan2.param,
|
|
719
|
+
executor: async (taskParam) => {
|
|
720
|
+
const scrollToEventName = taskParam.scrollType;
|
|
721
|
+
const innerHeight = await this.page.evaluate(
|
|
722
|
+
() => window.innerHeight
|
|
723
|
+
);
|
|
724
|
+
switch (scrollToEventName) {
|
|
725
|
+
case "ScrollUntilTop":
|
|
726
|
+
await this.page.mouse.wheel(0, -9999999);
|
|
727
|
+
break;
|
|
728
|
+
case "ScrollUntilBottom":
|
|
729
|
+
await this.page.mouse.wheel(0, 9999999);
|
|
730
|
+
break;
|
|
731
|
+
case "ScrollUp":
|
|
732
|
+
await this.page.mouse.wheel(0, -innerHeight);
|
|
733
|
+
break;
|
|
734
|
+
case "ScrollDown":
|
|
735
|
+
await this.page.mouse.wheel(0, innerHeight);
|
|
736
|
+
break;
|
|
737
|
+
default:
|
|
738
|
+
console.error(
|
|
739
|
+
"Unknown scroll event type:",
|
|
740
|
+
scrollToEventName
|
|
741
|
+
);
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
};
|
|
745
|
+
return taskActionScroll;
|
|
746
|
+
}
|
|
747
|
+
if (plan2.type === "Sleep") {
|
|
748
|
+
const taskActionSleep = {
|
|
749
|
+
type: "Action",
|
|
750
|
+
subType: "Sleep",
|
|
751
|
+
param: plan2.param,
|
|
752
|
+
executor: async (taskParam) => {
|
|
753
|
+
(0, import_node_assert2.default)(taskParam.timeMs, "No time to sleep");
|
|
754
|
+
await (0, import_utils2.sleep)(taskParam.timeMs);
|
|
755
|
+
}
|
|
756
|
+
};
|
|
757
|
+
return taskActionSleep;
|
|
758
|
+
}
|
|
759
|
+
if (plan2.type === "Error") {
|
|
760
|
+
const taskActionError = {
|
|
761
|
+
type: "Action",
|
|
762
|
+
subType: "Error",
|
|
763
|
+
param: plan2.param,
|
|
764
|
+
executor: async (taskParam) => {
|
|
765
|
+
(0, import_node_assert2.default)(
|
|
766
|
+
taskParam.thought,
|
|
767
|
+
"An error occurred, but no thought provided"
|
|
768
|
+
);
|
|
769
|
+
throw new Error(taskParam.thought);
|
|
770
|
+
}
|
|
771
|
+
};
|
|
772
|
+
return taskActionError;
|
|
773
|
+
}
|
|
774
|
+
throw new Error(`Unknown or Unsupported task type: ${plan2.type}`);
|
|
775
|
+
}).map((task) => {
|
|
776
|
+
return this.wrapExecutorWithScreenshot(task);
|
|
777
|
+
});
|
|
778
|
+
return tasks;
|
|
779
|
+
}
|
|
780
|
+
async action(userPrompt) {
|
|
781
|
+
const taskExecutor = new import_core.Executor(userPrompt);
|
|
782
|
+
let plans = [];
|
|
783
|
+
const planningTask = {
|
|
784
|
+
type: "Planning",
|
|
785
|
+
param: {
|
|
786
|
+
userPrompt
|
|
787
|
+
},
|
|
788
|
+
executor: async (param) => {
|
|
789
|
+
const pageContext = await this.insight.contextRetrieverFn();
|
|
790
|
+
let planResult;
|
|
791
|
+
const planCache = this.taskCache.readCache(
|
|
792
|
+
pageContext,
|
|
793
|
+
"plan",
|
|
794
|
+
userPrompt
|
|
795
|
+
);
|
|
796
|
+
if (planCache) {
|
|
797
|
+
planResult = planCache;
|
|
798
|
+
} else {
|
|
799
|
+
planResult = await (0, import_core.plan)(param.userPrompt, {
|
|
800
|
+
context: pageContext
|
|
801
|
+
});
|
|
802
|
+
}
|
|
803
|
+
(0, import_node_assert2.default)(planResult.plans.length > 0, "No plans found");
|
|
804
|
+
plans = planResult.plans;
|
|
805
|
+
this.taskCache.saveCache({
|
|
806
|
+
type: "plan",
|
|
807
|
+
pageContext: {
|
|
808
|
+
url: pageContext.url,
|
|
809
|
+
size: pageContext.size
|
|
810
|
+
},
|
|
811
|
+
prompt: userPrompt,
|
|
812
|
+
response: planResult
|
|
813
|
+
});
|
|
814
|
+
return {
|
|
815
|
+
output: planResult,
|
|
816
|
+
cache: {
|
|
817
|
+
hit: Boolean(planCache)
|
|
818
|
+
}
|
|
819
|
+
};
|
|
820
|
+
}
|
|
821
|
+
};
|
|
822
|
+
await taskExecutor.append(this.wrapExecutorWithScreenshot(planningTask));
|
|
823
|
+
let output = await taskExecutor.flush();
|
|
824
|
+
if (taskExecutor.isInErrorState()) {
|
|
825
|
+
return {
|
|
826
|
+
output,
|
|
827
|
+
executor: taskExecutor
|
|
828
|
+
};
|
|
829
|
+
}
|
|
830
|
+
const executables = await this.convertPlanToExecutable(plans);
|
|
831
|
+
await taskExecutor.append(executables);
|
|
832
|
+
output = await taskExecutor.flush();
|
|
833
|
+
return {
|
|
834
|
+
output,
|
|
835
|
+
executor: taskExecutor
|
|
836
|
+
};
|
|
837
|
+
}
|
|
838
|
+
async query(demand) {
|
|
839
|
+
const description = typeof demand === "string" ? demand : JSON.stringify(demand);
|
|
840
|
+
const taskExecutor = new import_core.Executor(description);
|
|
841
|
+
const queryTask = {
|
|
842
|
+
type: "Insight",
|
|
843
|
+
subType: "Query",
|
|
844
|
+
param: {
|
|
845
|
+
dataDemand: demand
|
|
846
|
+
},
|
|
847
|
+
executor: async (param) => {
|
|
848
|
+
let insightDump;
|
|
849
|
+
const dumpCollector = (dump) => {
|
|
850
|
+
insightDump = dump;
|
|
851
|
+
};
|
|
852
|
+
this.insight.onceDumpUpdatedFn = dumpCollector;
|
|
853
|
+
const data = await this.insight.extract(param.dataDemand);
|
|
854
|
+
return {
|
|
855
|
+
output: data,
|
|
856
|
+
log: { dump: insightDump }
|
|
857
|
+
};
|
|
858
|
+
}
|
|
859
|
+
};
|
|
860
|
+
await taskExecutor.append(this.wrapExecutorWithScreenshot(queryTask));
|
|
861
|
+
const output = await taskExecutor.flush();
|
|
862
|
+
return {
|
|
863
|
+
output,
|
|
864
|
+
executor: taskExecutor
|
|
865
|
+
};
|
|
866
|
+
}
|
|
867
|
+
async assert(assertion) {
|
|
868
|
+
const description = `assert: ${assertion}`;
|
|
869
|
+
const taskExecutor = new import_core.Executor(description);
|
|
870
|
+
const assertionPlan = {
|
|
871
|
+
type: "Assert",
|
|
872
|
+
param: {
|
|
873
|
+
assertion
|
|
874
|
+
}
|
|
875
|
+
};
|
|
876
|
+
const assertTask = await this.convertPlanToExecutable([assertionPlan]);
|
|
877
|
+
await taskExecutor.append(this.wrapExecutorWithScreenshot(assertTask[0]));
|
|
878
|
+
const output = await taskExecutor.flush();
|
|
879
|
+
return {
|
|
880
|
+
output,
|
|
881
|
+
executor: taskExecutor
|
|
882
|
+
};
|
|
883
|
+
}
|
|
884
|
+
async waitFor(assertion, opt) {
|
|
885
|
+
const description = `waitFor: ${assertion}`;
|
|
886
|
+
const taskExecutor = new import_core.Executor(description);
|
|
887
|
+
const { timeoutMs, checkIntervalMs } = opt;
|
|
888
|
+
(0, import_node_assert2.default)(assertion, "No assertion for waitFor");
|
|
889
|
+
(0, import_node_assert2.default)(timeoutMs, "No timeoutMs for waitFor");
|
|
890
|
+
(0, import_node_assert2.default)(checkIntervalMs, "No checkIntervalMs for waitFor");
|
|
891
|
+
const overallStartTime = Date.now();
|
|
892
|
+
let startTime = Date.now();
|
|
893
|
+
let errorThought = "";
|
|
894
|
+
while (Date.now() - overallStartTime < timeoutMs) {
|
|
895
|
+
startTime = Date.now();
|
|
896
|
+
const assertPlan = {
|
|
897
|
+
type: "AssertWithoutThrow",
|
|
898
|
+
param: {
|
|
899
|
+
assertion
|
|
900
|
+
}
|
|
901
|
+
};
|
|
902
|
+
const assertTask = await this.convertPlanToExecutable([assertPlan]);
|
|
903
|
+
await taskExecutor.append(this.wrapExecutorWithScreenshot(assertTask[0]));
|
|
904
|
+
const output = await taskExecutor.flush();
|
|
905
|
+
if (output.pass) {
|
|
906
|
+
return {
|
|
907
|
+
output: void 0,
|
|
908
|
+
executor: taskExecutor
|
|
909
|
+
};
|
|
910
|
+
}
|
|
911
|
+
errorThought = output.thought;
|
|
912
|
+
const now = Date.now();
|
|
913
|
+
if (now - startTime < checkIntervalMs) {
|
|
914
|
+
const timeRemaining = checkIntervalMs - (now - startTime);
|
|
915
|
+
const sleepPlan = {
|
|
916
|
+
type: "Sleep",
|
|
917
|
+
param: {
|
|
918
|
+
timeMs: timeRemaining
|
|
919
|
+
}
|
|
920
|
+
};
|
|
921
|
+
const sleepTask = await this.convertPlanToExecutable([sleepPlan]);
|
|
922
|
+
await taskExecutor.append(
|
|
923
|
+
this.wrapExecutorWithScreenshot(sleepTask[0])
|
|
924
|
+
);
|
|
925
|
+
await taskExecutor.flush();
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
const errorPlan = {
|
|
929
|
+
type: "Error",
|
|
930
|
+
param: {
|
|
931
|
+
thought: `waitFor timeout: ${errorThought}`
|
|
932
|
+
}
|
|
933
|
+
};
|
|
934
|
+
const errorTask = await this.convertPlanToExecutable([errorPlan]);
|
|
935
|
+
await taskExecutor.append(errorTask[0]);
|
|
936
|
+
await taskExecutor.flush();
|
|
937
|
+
return {
|
|
938
|
+
output: void 0,
|
|
939
|
+
executor: taskExecutor
|
|
940
|
+
};
|
|
941
|
+
}
|
|
942
|
+
};
|
|
943
|
+
|
|
944
|
+
// src/common/agent.ts
|
|
945
|
+
var PageAgent = class {
|
|
946
|
+
constructor(page, opts) {
|
|
947
|
+
this.page = page;
|
|
948
|
+
this.opts = Object.assign(
|
|
949
|
+
{
|
|
950
|
+
generateReport: true,
|
|
951
|
+
autoPrintReportMsg: true,
|
|
952
|
+
groupName: "Midscene Report",
|
|
953
|
+
groupDescription: ""
|
|
954
|
+
},
|
|
955
|
+
opts || {}
|
|
956
|
+
);
|
|
957
|
+
this.dump = {
|
|
958
|
+
groupName: this.opts.groupName,
|
|
959
|
+
groupDescription: this.opts.groupDescription,
|
|
960
|
+
executions: []
|
|
961
|
+
};
|
|
962
|
+
this.taskExecutor = new PageTaskExecutor(this.page, {
|
|
963
|
+
cache: (opts == null ? void 0 : opts.cache) || { aiTasks: [] }
|
|
964
|
+
});
|
|
965
|
+
this.reportFileName = reportFileName((opts == null ? void 0 : opts.testId) || "web");
|
|
966
|
+
}
|
|
967
|
+
appendExecutionDump(execution) {
|
|
968
|
+
const currentDump = this.dump;
|
|
969
|
+
currentDump.executions.push(execution);
|
|
970
|
+
}
|
|
971
|
+
dumpDataString() {
|
|
972
|
+
this.dump.groupName = this.opts.groupName;
|
|
973
|
+
this.dump.groupDescription = this.opts.groupDescription;
|
|
974
|
+
return (0, import_utils4.stringifyDumpData)(this.dump);
|
|
975
|
+
}
|
|
976
|
+
writeOutActionDumps() {
|
|
977
|
+
const { generateReport, autoPrintReportMsg } = this.opts;
|
|
978
|
+
this.reportFile = (0, import_utils4.writeLogFile)({
|
|
979
|
+
fileName: this.reportFileName,
|
|
980
|
+
fileExt: import_utils4.groupedActionDumpFileExt,
|
|
981
|
+
fileContent: this.dumpDataString(),
|
|
982
|
+
type: "dump",
|
|
983
|
+
generateReport
|
|
984
|
+
});
|
|
985
|
+
if (generateReport && autoPrintReportMsg) {
|
|
986
|
+
printReportMsg(this.reportFile);
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
async aiAction(taskPrompt) {
|
|
990
|
+
const { executor } = await this.taskExecutor.action(taskPrompt);
|
|
991
|
+
this.appendExecutionDump(executor.dump());
|
|
992
|
+
this.writeOutActionDumps();
|
|
993
|
+
if (executor.isInErrorState()) {
|
|
994
|
+
const errorTask = executor.latestErrorTask();
|
|
995
|
+
throw new Error(`${errorTask == null ? void 0 : errorTask.error}
|
|
996
|
+
${errorTask == null ? void 0 : errorTask.errorStack}`);
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
async aiQuery(demand) {
|
|
1000
|
+
const { output, executor } = await this.taskExecutor.query(demand);
|
|
1001
|
+
this.appendExecutionDump(executor.dump());
|
|
1002
|
+
this.writeOutActionDumps();
|
|
1003
|
+
if (executor.isInErrorState()) {
|
|
1004
|
+
const errorTask = executor.latestErrorTask();
|
|
1005
|
+
throw new Error(`${errorTask == null ? void 0 : errorTask.error}
|
|
1006
|
+
${errorTask == null ? void 0 : errorTask.errorStack}`);
|
|
1007
|
+
}
|
|
1008
|
+
return output;
|
|
1009
|
+
}
|
|
1010
|
+
async aiAssert(assertion, msg) {
|
|
1011
|
+
const { output, executor } = await this.taskExecutor.assert(assertion);
|
|
1012
|
+
this.appendExecutionDump(executor.dump());
|
|
1013
|
+
this.writeOutActionDumps();
|
|
1014
|
+
if (!(output == null ? void 0 : output.pass)) {
|
|
1015
|
+
const errMsg = msg || `Assertion failed: ${assertion}`;
|
|
1016
|
+
const reasonMsg = `Reason: ${output == null ? void 0 : output.thought} || (no_reason)`;
|
|
1017
|
+
throw new Error(`${errMsg}
|
|
1018
|
+
${reasonMsg}`);
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
async aiWaitFor(assertion, opt) {
|
|
1022
|
+
const { executor } = await this.taskExecutor.waitFor(assertion, {
|
|
1023
|
+
timeoutMs: (opt == null ? void 0 : opt.timeoutMs) || 15 * 1e3,
|
|
1024
|
+
checkIntervalMs: (opt == null ? void 0 : opt.checkIntervalMs) || 3 * 1e3,
|
|
1025
|
+
assertion
|
|
1026
|
+
});
|
|
1027
|
+
this.appendExecutionDump(executor.dump());
|
|
1028
|
+
this.writeOutActionDumps();
|
|
1029
|
+
if (executor.isInErrorState()) {
|
|
1030
|
+
const errorTask = executor.latestErrorTask();
|
|
1031
|
+
throw new Error(`${errorTask == null ? void 0 : errorTask.error}
|
|
1032
|
+
${errorTask == null ? void 0 : errorTask.errorStack}`);
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
async ai(taskPrompt, type = "action") {
|
|
1036
|
+
if (type === "action") {
|
|
1037
|
+
return this.aiAction(taskPrompt);
|
|
1038
|
+
}
|
|
1039
|
+
if (type === "query") {
|
|
1040
|
+
return this.aiQuery(taskPrompt);
|
|
1041
|
+
}
|
|
1042
|
+
if (type === "assert") {
|
|
1043
|
+
return this.aiAssert(taskPrompt);
|
|
1044
|
+
}
|
|
1045
|
+
throw new Error(
|
|
1046
|
+
`Unknown type: ${type}, only support 'action', 'query', 'assert'`
|
|
1047
|
+
);
|
|
1048
|
+
}
|
|
1049
|
+
};
|
|
1050
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
1051
|
+
0 && (module.exports = {
|
|
1052
|
+
PuppeteerAgent
|
|
1053
|
+
});
|