@midscene/web 0.7.1 → 0.7.2-beta-20241024094141.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.
package/dist/lib/index.js CHANGED
@@ -46,6 +46,26 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
46
46
  mod
47
47
  ));
48
48
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
49
+ var __async = (__this, __arguments, generator) => {
50
+ return new Promise((resolve, reject) => {
51
+ var fulfilled = (value) => {
52
+ try {
53
+ step(generator.next(value));
54
+ } catch (e) {
55
+ reject(e);
56
+ }
57
+ };
58
+ var rejected = (value) => {
59
+ try {
60
+ step(generator.throw(value));
61
+ } catch (e) {
62
+ reject(e);
63
+ }
64
+ };
65
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
66
+ step((generator = generator.apply(__this, __arguments)).next());
67
+ });
68
+ };
49
69
 
50
70
  // ../../node_modules/.pnpm/dayjs@1.11.11/node_modules/dayjs/dayjs.min.js
51
71
  var require_dayjs_min = __commonJS({
@@ -869,37 +889,38 @@ __export(src_exports, {
869
889
  PlaywrightAgent: () => PageAgent,
870
890
  PlaywrightAiFixture: () => PlaywrightAiFixture,
871
891
  PuppeteerAgent: () => PuppeteerAgent,
892
+ StaticPageAgent: () => StaticPageAgent,
872
893
  generateExtractData: () => generateExtractData
873
894
  });
874
895
  module.exports = __toCommonJS(src_exports);
875
896
 
876
897
  // src/playwright/ai-fixture.ts
877
- var import_node_crypto2 = require("crypto");
898
+ var import_node_crypto = require("crypto");
878
899
 
879
900
  // src/common/agent.ts
880
- var import_utils5 = require("@midscene/core/utils");
901
+ var import_utils7 = require("@midscene/core/utils");
881
902
 
882
903
  // src/common/tasks.ts
883
904
  var import_node_assert2 = __toESM(require("assert"));
884
905
  var import_core = require("@midscene/core");
885
- var import_utils3 = require("@midscene/core/utils");
886
- var import_img3 = require("@midscene/shared/img");
906
+ var import_utils5 = require("@midscene/core/utils");
887
907
 
888
908
  // src/common/task-cache.ts
889
909
  var import_node_fs2 = require("fs");
890
910
  var import_node_path2 = require("path");
891
- var import_utils = require("@midscene/core/utils");
911
+ var import_utils2 = require("@midscene/core/utils");
892
912
  var import_fs2 = require("@midscene/shared/fs");
913
+ var import_utils3 = require("@midscene/shared/utils");
893
914
 
894
915
  // src/common/utils.ts
895
916
  var import_node_assert = __toESM(require("assert"));
896
- var import_node_crypto = require("crypto");
897
917
  var import_node_fs = require("fs");
898
918
  var import_node_path = __toESM(require("path"));
899
919
  var import_constants = require("@midscene/shared/constants");
900
920
  var import_fs = require("@midscene/shared/fs");
901
921
  var import_img = require("@midscene/shared/img");
902
922
  var import_img2 = require("@midscene/shared/img");
923
+ var import_utils = require("@midscene/shared/utils");
903
924
  var import_dayjs = __toESM(require_dayjs_min());
904
925
 
905
926
  // src/web-element.ts
@@ -928,63 +949,68 @@ var WebElementInfo = class {
928
949
  };
929
950
 
930
951
  // src/common/utils.ts
931
- async function parseContextFromWebPage(page, _opt) {
932
- (0, import_node_assert.default)(page, "page is required");
933
- if (page._forceUsePageContext) {
934
- return await page._forceUsePageContext();
935
- }
936
- const url = page.url();
937
- const file = await page.screenshot();
938
- const screenshotBase64 = (0, import_img.base64Encoded)(file);
939
- const captureElementSnapshot = await page.getElementInfos();
940
- const elementsInfo = await alignElements(captureElementSnapshot, page);
941
- const elementsPositionInfoWithoutText = elementsInfo.filter((elementInfo) => {
942
- if (elementInfo.attributes.nodeType === import_constants.NodeType.TEXT) {
943
- return false;
952
+ function parseContextFromWebPage(page, _opt) {
953
+ return __async(this, null, function* () {
954
+ (0, import_node_assert.default)(page, "page is required");
955
+ if (page._forceUsePageContext) {
956
+ return yield page._forceUsePageContext();
944
957
  }
945
- return true;
946
- });
947
- const size = await (0, import_img.imageInfoOfBase64)(screenshotBase64);
948
- const screenshotBase64WithElementMarker = await (0, import_img2.compositeElementInfoImg)({
949
- inputImgBase64: screenshotBase64.split(";base64,").pop(),
950
- elementsPositionInfo: elementsPositionInfoWithoutText
958
+ const url = page.url();
959
+ const screenshotBase64 = yield page.screenshotBase64();
960
+ const captureElementSnapshot = yield page.getElementInfos();
961
+ const elementsInfo = yield alignElements(captureElementSnapshot, page);
962
+ const elementsPositionInfoWithoutText = elementsInfo.filter((elementInfo) => {
963
+ if (elementInfo.attributes.nodeType === import_constants.NodeType.TEXT) {
964
+ return false;
965
+ }
966
+ return true;
967
+ });
968
+ const size = yield (0, import_img.imageInfoOfBase64)(screenshotBase64);
969
+ const screenshotBase64WithElementMarker = yield (0, import_img2.compositeElementInfoImg)({
970
+ inputImgBase64: screenshotBase64,
971
+ elementsPositionInfo: elementsPositionInfoWithoutText
972
+ });
973
+ return {
974
+ content: elementsInfo,
975
+ size,
976
+ screenshotBase64,
977
+ screenshotBase64WithElementMarker: `data:image/png;base64,${screenshotBase64WithElementMarker}`,
978
+ url
979
+ };
951
980
  });
952
- return {
953
- content: elementsInfo,
954
- size,
955
- screenshotBase64,
956
- screenshotBase64WithElementMarker: `data:image/png;base64,${screenshotBase64WithElementMarker}`,
957
- url
958
- };
959
981
  }
960
- async function getExtraReturnLogic() {
961
- const pathDir = (0, import_fs.findNearestPackageJson)(__dirname);
962
- (0, import_node_assert.default)(pathDir, `can't find pathDir, with ${__dirname}`);
963
- const scriptPath = import_node_path.default.join(pathDir, "./dist/script/htmlElement.js");
964
- const elementInfosScriptContent = (0, import_node_fs.readFileSync)(scriptPath, "utf-8");
965
- return `${elementInfosScriptContent}midscene_element_inspector.webExtractTextWithPosition()`;
982
+ function getExtraReturnLogic() {
983
+ return __async(this, null, function* () {
984
+ const pathDir = (0, import_fs.findNearestPackageJson)(__dirname);
985
+ (0, import_node_assert.default)(pathDir, `can't find pathDir, with ${__dirname}`);
986
+ const scriptPath = import_node_path.default.join(pathDir, "./dist/script/htmlElement.js");
987
+ const elementInfosScriptContent = (0, import_node_fs.readFileSync)(scriptPath, "utf-8");
988
+ return `${elementInfosScriptContent}midscene_element_inspector.webExtractTextWithPosition()`;
989
+ });
966
990
  }
967
991
  var sizeThreshold = 3;
968
- async function alignElements(elements, page) {
969
- const validElements = elements.filter((item) => {
970
- return item.rect.height >= sizeThreshold && item.rect.width >= sizeThreshold;
992
+ function alignElements(elements, page) {
993
+ return __async(this, null, function* () {
994
+ const validElements = elements.filter((item) => {
995
+ return item.rect.height >= sizeThreshold && item.rect.width >= sizeThreshold;
996
+ });
997
+ const textsAligned = [];
998
+ for (const item of validElements) {
999
+ const { rect, id, content, attributes, locator, indexId } = item;
1000
+ textsAligned.push(
1001
+ new WebElementInfo({
1002
+ rect,
1003
+ locator,
1004
+ id,
1005
+ content,
1006
+ attributes,
1007
+ page,
1008
+ indexId
1009
+ })
1010
+ );
1011
+ }
1012
+ return textsAligned;
971
1013
  });
972
- const textsAligned = [];
973
- for (const item of validElements) {
974
- const { rect, id, content, attributes, locator, indexId } = item;
975
- textsAligned.push(
976
- new WebElementInfo({
977
- rect,
978
- locator,
979
- id,
980
- content,
981
- attributes,
982
- page,
983
- indexId
984
- })
985
- );
986
- }
987
- return textsAligned;
988
1014
  }
989
1015
  function reportFileName(tag = "web") {
990
1016
  const dateTimeInFileName = (0, import_dayjs.default)().format("YYYY-MM-DD_HH-mm-ss-SSS");
@@ -1015,7 +1041,7 @@ var testFileIndex = /* @__PURE__ */ new Map();
1015
1041
  function generateCacheId(fileName) {
1016
1042
  let taskFile = fileName || getCurrentExecutionFile();
1017
1043
  if (!taskFile) {
1018
- taskFile = (0, import_node_crypto.randomUUID)();
1044
+ taskFile = (0, import_utils.uuid)();
1019
1045
  console.warn(
1020
1046
  "Midscene - using random UUID for cache id. Cache may be invalid."
1021
1047
  );
@@ -1034,7 +1060,7 @@ function generateCacheId(fileName) {
1034
1060
  // src/common/task-cache.ts
1035
1061
  var TaskCache = class {
1036
1062
  constructor(opts) {
1037
- this.midscenePkgInfo = (0, import_fs2.getMidscenePkgInfo)(__dirname);
1063
+ this.midscenePkgInfo = (0, import_fs2.getRunningPkgInfo)();
1038
1064
  this.cacheId = generateCacheId(opts == null ? void 0 : opts.fileName);
1039
1065
  this.cache = this.readCacheFromFile() || {
1040
1066
  aiTasks: []
@@ -1116,11 +1142,17 @@ var TaskCache = class {
1116
1142
  return this.newCache;
1117
1143
  }
1118
1144
  readCacheFromFile() {
1119
- const cacheFile = (0, import_node_path2.join)((0, import_utils.getLogDirByType)("cache"), `${this.cacheId}.json`);
1145
+ if (import_utils3.ifInBrowser) {
1146
+ return void 0;
1147
+ }
1148
+ const cacheFile = (0, import_node_path2.join)((0, import_utils2.getLogDirByType)("cache"), `${this.cacheId}.json`);
1120
1149
  if (process.env.MIDSCENE_CACHE === "true" && (0, import_node_fs2.existsSync)(cacheFile)) {
1121
1150
  try {
1122
1151
  const data = (0, import_node_fs2.readFileSync)(cacheFile, "utf8");
1123
1152
  const jsonData = JSON.parse(data);
1153
+ if (!this.midscenePkgInfo) {
1154
+ return void 0;
1155
+ }
1124
1156
  if (jsonData.pkgName !== this.midscenePkgInfo.name || jsonData.pkgVersion !== this.midscenePkgInfo.version) {
1125
1157
  return void 0;
1126
1158
  }
@@ -1132,11 +1164,14 @@ var TaskCache = class {
1132
1164
  return void 0;
1133
1165
  }
1134
1166
  writeCacheToFile() {
1135
- const midscenePkgInfo = (0, import_fs2.getMidscenePkgInfo)(__dirname);
1136
- (0, import_utils.writeLogFile)({
1167
+ const midscenePkgInfo = (0, import_fs2.getRunningPkgInfo)();
1168
+ if (!midscenePkgInfo) {
1169
+ return;
1170
+ }
1171
+ (0, import_utils2.writeLogFile)({
1137
1172
  fileName: `${this.cacheId}`,
1138
1173
  fileExt: "json",
1139
- fileContent: (0, import_utils.stringifyDumpData)(
1174
+ fileContent: (0, import_utils2.stringifyDumpData)(
1140
1175
  __spreadValues({
1141
1176
  pkgName: midscenePkgInfo.name,
1142
1177
  pkgVersion: midscenePkgInfo.version,
@@ -1153,423 +1188,435 @@ var TaskCache = class {
1153
1188
  var PageTaskExecutor = class {
1154
1189
  constructor(page, opts) {
1155
1190
  this.page = page;
1156
- this.insight = new import_core.Insight(async () => {
1157
- return await parseContextFromWebPage(page);
1158
- });
1191
+ this.insight = new import_core.Insight(() => __async(this, null, function* () {
1192
+ return yield parseContextFromWebPage(page);
1193
+ }));
1159
1194
  this.taskCache = new TaskCache({
1160
1195
  fileName: opts == null ? void 0 : opts.cacheId
1161
1196
  });
1162
1197
  }
1163
- async recordScreenshot(timing) {
1164
- const file = await this.page.screenshot();
1165
- const item = {
1166
- type: "screenshot",
1167
- ts: Date.now(),
1168
- screenshot: (0, import_img3.base64Encoded)(file),
1169
- timing
1170
- };
1171
- return item;
1198
+ recordScreenshot(timing) {
1199
+ return __async(this, null, function* () {
1200
+ const base64 = yield this.page.screenshotBase64();
1201
+ const item = {
1202
+ type: "screenshot",
1203
+ ts: Date.now(),
1204
+ screenshot: base64,
1205
+ timing
1206
+ };
1207
+ return item;
1208
+ });
1172
1209
  }
1173
1210
  wrapExecutorWithScreenshot(taskApply) {
1174
1211
  const taskWithScreenshot = __spreadProps(__spreadValues({}, taskApply), {
1175
- executor: async (param, context, ...args) => {
1212
+ executor: (param, context, ...args) => __async(this, null, function* () {
1176
1213
  const recorder = [];
1177
1214
  const { task } = context;
1178
1215
  task.recorder = recorder;
1179
- const shot = await this.recordScreenshot(`before ${task.type}`);
1216
+ const shot = yield this.recordScreenshot(`before ${task.type}`);
1180
1217
  recorder.push(shot);
1181
- const result = await taskApply.executor(param, context, ...args);
1218
+ const result = yield taskApply.executor(param, context, ...args);
1182
1219
  if (taskApply.type === "Action") {
1183
- await (0, import_utils3.sleep)(1e3);
1184
- const shot2 = await this.recordScreenshot("after Action");
1220
+ yield (0, import_utils5.sleep)(1e3);
1221
+ const shot2 = yield this.recordScreenshot("after Action");
1185
1222
  recorder.push(shot2);
1186
1223
  }
1187
1224
  return result;
1188
- }
1225
+ })
1189
1226
  });
1190
1227
  return taskWithScreenshot;
1191
1228
  }
1192
- async convertPlanToExecutable(plans, cacheGroup) {
1193
- const tasks = plans.map((plan2) => {
1194
- if (plan2.type === "Locate") {
1195
- const taskFind = {
1196
- type: "Insight",
1197
- subType: "Locate",
1198
- param: plan2.param,
1199
- executor: async (param, taskContext) => {
1200
- const { task } = taskContext;
1201
- let insightDump;
1202
- const dumpCollector = (dump) => {
1203
- insightDump = dump;
1204
- };
1205
- this.insight.onceDumpUpdatedFn = dumpCollector;
1206
- const pageContext = await this.insight.contextRetrieverFn();
1207
- const locateCache = cacheGroup == null ? void 0 : cacheGroup.readCache(
1208
- pageContext,
1209
- "locate",
1210
- param.prompt
1211
- );
1212
- let locateResult;
1213
- const callAI = this.insight.aiVendorFn;
1214
- const element = await this.insight.locate(param.prompt, {
1215
- quickAnswer: plan2.quickAnswer,
1216
- callAI: async (...message) => {
1217
- if (locateCache) {
1218
- locateResult = locateCache;
1219
- return Promise.resolve(locateCache);
1220
- }
1221
- locateResult = await callAI(...message);
1222
- (0, import_node_assert2.default)(locateResult);
1223
- return locateResult;
1224
- }
1225
- });
1226
- if (locateResult) {
1227
- cacheGroup == null ? void 0 : cacheGroup.saveCache({
1228
- type: "locate",
1229
- pageContext: {
1230
- url: pageContext.url,
1231
- size: pageContext.size
1232
- },
1233
- prompt: param.prompt,
1234
- response: locateResult
1235
- });
1236
- }
1237
- if (!element) {
1238
- task.log = {
1239
- dump: insightDump
1229
+ convertPlanToExecutable(plans, cacheGroup) {
1230
+ return __async(this, null, function* () {
1231
+ const tasks = plans.map((plan2) => {
1232
+ if (plan2.type === "Locate") {
1233
+ const taskFind = {
1234
+ type: "Insight",
1235
+ subType: "Locate",
1236
+ param: plan2.param,
1237
+ executor: (param, taskContext) => __async(this, null, function* () {
1238
+ const { task } = taskContext;
1239
+ let insightDump;
1240
+ const dumpCollector = (dump) => {
1241
+ insightDump = dump;
1240
1242
  };
1241
- throw new Error(`Element not found: ${param.prompt}`);
1242
- }
1243
- return {
1244
- output: {
1245
- element
1246
- },
1247
- log: {
1248
- dump: insightDump
1249
- },
1250
- cache: {
1251
- hit: Boolean(locateCache)
1243
+ this.insight.onceDumpUpdatedFn = dumpCollector;
1244
+ const pageContext = yield this.insight.contextRetrieverFn();
1245
+ const locateCache = cacheGroup == null ? void 0 : cacheGroup.readCache(
1246
+ pageContext,
1247
+ "locate",
1248
+ param.prompt
1249
+ );
1250
+ let locateResult;
1251
+ const callAI = this.insight.aiVendorFn;
1252
+ const element = yield this.insight.locate(param.prompt, {
1253
+ quickAnswer: plan2.quickAnswer,
1254
+ callAI: (...message) => __async(this, null, function* () {
1255
+ if (locateCache) {
1256
+ locateResult = locateCache;
1257
+ return Promise.resolve(locateCache);
1258
+ }
1259
+ locateResult = yield callAI(...message);
1260
+ (0, import_node_assert2.default)(locateResult);
1261
+ return locateResult;
1262
+ })
1263
+ });
1264
+ if (locateResult) {
1265
+ cacheGroup == null ? void 0 : cacheGroup.saveCache({
1266
+ type: "locate",
1267
+ pageContext: {
1268
+ url: pageContext.url,
1269
+ size: pageContext.size
1270
+ },
1271
+ prompt: param.prompt,
1272
+ response: locateResult
1273
+ });
1252
1274
  }
1253
- };
1254
- }
1255
- };
1256
- return taskFind;
1257
- }
1258
- if (plan2.type === "Assert" || plan2.type === "AssertWithoutThrow") {
1259
- const assertPlan = plan2;
1260
- const taskAssert = {
1261
- type: "Insight",
1262
- subType: "Assert",
1263
- param: assertPlan.param,
1264
- executor: async (param, taskContext) => {
1265
- const { task } = taskContext;
1266
- let insightDump;
1267
- const dumpCollector = (dump) => {
1268
- insightDump = dump;
1269
- };
1270
- this.insight.onceDumpUpdatedFn = dumpCollector;
1271
- const assertion = await this.insight.assert(
1272
- assertPlan.param.assertion
1273
- );
1274
- if (!assertion.pass) {
1275
- if (plan2.type === "Assert") {
1276
- task.output = assertion;
1275
+ if (!element) {
1277
1276
  task.log = {
1278
1277
  dump: insightDump
1279
1278
  };
1280
- throw new Error(
1281
- assertion.thought || "Assertion failed without reason"
1282
- );
1279
+ throw new Error(`Element not found: ${param.prompt}`);
1283
1280
  }
1284
- task.error = assertion.thought;
1285
- }
1286
- return {
1287
- output: assertion,
1288
- log: {
1289
- dump: insightDump
1281
+ return {
1282
+ output: {
1283
+ element
1284
+ },
1285
+ log: {
1286
+ dump: insightDump
1287
+ },
1288
+ cache: {
1289
+ hit: Boolean(locateCache)
1290
+ }
1291
+ };
1292
+ })
1293
+ };
1294
+ return taskFind;
1295
+ }
1296
+ if (plan2.type === "Assert" || plan2.type === "AssertWithoutThrow") {
1297
+ const assertPlan = plan2;
1298
+ const taskAssert = {
1299
+ type: "Insight",
1300
+ subType: "Assert",
1301
+ param: assertPlan.param,
1302
+ executor: (param, taskContext) => __async(this, null, function* () {
1303
+ const { task } = taskContext;
1304
+ let insightDump;
1305
+ const dumpCollector = (dump) => {
1306
+ insightDump = dump;
1307
+ };
1308
+ this.insight.onceDumpUpdatedFn = dumpCollector;
1309
+ const assertion = yield this.insight.assert(
1310
+ assertPlan.param.assertion
1311
+ );
1312
+ if (!assertion.pass) {
1313
+ if (plan2.type === "Assert") {
1314
+ task.output = assertion;
1315
+ task.log = {
1316
+ dump: insightDump
1317
+ };
1318
+ throw new Error(
1319
+ assertion.thought || "Assertion failed without reason"
1320
+ );
1321
+ }
1322
+ task.error = assertion.thought;
1290
1323
  }
1291
- };
1292
- }
1293
- };
1294
- return taskAssert;
1295
- }
1296
- if (plan2.type === "Input") {
1297
- const taskActionInput = {
1298
- type: "Action",
1299
- subType: "Input",
1300
- param: plan2.param,
1301
- executor: async (taskParam, { element }) => {
1302
- if (element) {
1303
- await this.page.clearInput(element);
1304
- if (taskParam.value === "") {
1305
- return;
1324
+ return {
1325
+ output: assertion,
1326
+ log: {
1327
+ dump: insightDump
1328
+ }
1329
+ };
1330
+ })
1331
+ };
1332
+ return taskAssert;
1333
+ }
1334
+ if (plan2.type === "Input") {
1335
+ const taskActionInput = {
1336
+ type: "Action",
1337
+ subType: "Input",
1338
+ param: plan2.param,
1339
+ executor: (_0, _1) => __async(this, [_0, _1], function* (taskParam, { element }) {
1340
+ if (element) {
1341
+ yield this.page.clearInput(element);
1342
+ if (taskParam.value === "") {
1343
+ return;
1344
+ }
1345
+ yield this.page.keyboard.type(taskParam.value);
1306
1346
  }
1307
- await this.page.keyboard.type(taskParam.value);
1308
- }
1309
- }
1310
- };
1311
- return taskActionInput;
1312
- }
1313
- if (plan2.type === "KeyboardPress") {
1314
- const taskActionKeyboardPress = {
1315
- type: "Action",
1316
- subType: "KeyboardPress",
1317
- param: plan2.param,
1318
- executor: async (taskParam) => {
1319
- (0, import_node_assert2.default)(taskParam.value, "No key to press");
1320
- await this.page.keyboard.press(taskParam.value);
1321
- }
1322
- };
1323
- return taskActionKeyboardPress;
1324
- }
1325
- if (plan2.type === "Tap") {
1326
- const taskActionTap = {
1327
- type: "Action",
1328
- subType: "Tap",
1329
- executor: async (param, { element }) => {
1330
- (0, import_node_assert2.default)(element, "Element not found, cannot tap");
1331
- await this.page.mouse.click(
1332
- element.center[0],
1333
- element.center[1]
1334
- );
1335
- }
1336
- };
1337
- return taskActionTap;
1338
- }
1339
- if (plan2.type === "Hover") {
1340
- const taskActionHover = {
1341
- type: "Action",
1342
- subType: "Hover",
1343
- executor: async (param, { element }) => {
1344
- (0, import_node_assert2.default)(element, "Element not found, cannot hover");
1345
- await this.page.mouse.move(
1346
- element.center[0],
1347
- element.center[1]
1348
- );
1349
- }
1350
- };
1351
- return taskActionHover;
1352
- }
1353
- if (plan2.type === "Scroll") {
1354
- const taskActionScroll = {
1355
- type: "Action",
1356
- subType: "Scroll",
1357
- param: plan2.param,
1358
- executor: async (taskParam) => {
1359
- const scrollToEventName = taskParam.scrollType;
1360
- switch (scrollToEventName) {
1361
- case "scrollUntilTop":
1362
- await this.page.scrollUntilTop();
1363
- break;
1364
- case "scrollUntilBottom":
1365
- await this.page.scrollUntilBottom();
1366
- break;
1367
- case "scrollUpOneScreen":
1368
- await this.page.scrollUpOneScreen();
1369
- break;
1370
- case "scrollDownOneScreen":
1371
- await this.page.scrollDownOneScreen();
1372
- break;
1373
- default:
1374
- console.error(
1375
- "Unknown scroll event type:",
1376
- scrollToEventName
1377
- );
1378
- }
1379
- }
1380
- };
1381
- return taskActionScroll;
1382
- }
1383
- if (plan2.type === "Sleep") {
1384
- const taskActionSleep = {
1385
- type: "Action",
1386
- subType: "Sleep",
1387
- param: plan2.param,
1388
- executor: async (taskParam) => {
1389
- await (0, import_utils3.sleep)(taskParam.timeMs || 3e3);
1390
- }
1391
- };
1392
- return taskActionSleep;
1393
- }
1394
- if (plan2.type === "Error") {
1395
- const taskActionError = {
1396
- type: "Action",
1397
- subType: "Error",
1398
- param: plan2.param,
1399
- executor: async (taskParam) => {
1400
- (0, import_node_assert2.default)(
1401
- taskParam.thought,
1402
- "An error occurred, but no thought provided"
1403
- );
1404
- throw new Error(taskParam.thought);
1405
- }
1406
- };
1407
- return taskActionError;
1408
- }
1409
- throw new Error(`Unknown or Unsupported task type: ${plan2.type}`);
1410
- }).map((task) => {
1411
- return this.wrapExecutorWithScreenshot(task);
1347
+ })
1348
+ };
1349
+ return taskActionInput;
1350
+ }
1351
+ if (plan2.type === "KeyboardPress") {
1352
+ const taskActionKeyboardPress = {
1353
+ type: "Action",
1354
+ subType: "KeyboardPress",
1355
+ param: plan2.param,
1356
+ executor: (taskParam) => __async(this, null, function* () {
1357
+ (0, import_node_assert2.default)(taskParam.value, "No key to press");
1358
+ yield this.page.keyboard.press(taskParam.value);
1359
+ })
1360
+ };
1361
+ return taskActionKeyboardPress;
1362
+ }
1363
+ if (plan2.type === "Tap") {
1364
+ const taskActionTap = {
1365
+ type: "Action",
1366
+ subType: "Tap",
1367
+ executor: (_0, _1) => __async(this, [_0, _1], function* (param, { element }) {
1368
+ (0, import_node_assert2.default)(element, "Element not found, cannot tap");
1369
+ yield this.page.mouse.click(
1370
+ element.center[0],
1371
+ element.center[1]
1372
+ );
1373
+ })
1374
+ };
1375
+ return taskActionTap;
1376
+ }
1377
+ if (plan2.type === "Hover") {
1378
+ const taskActionHover = {
1379
+ type: "Action",
1380
+ subType: "Hover",
1381
+ executor: (_0, _1) => __async(this, [_0, _1], function* (param, { element }) {
1382
+ (0, import_node_assert2.default)(element, "Element not found, cannot hover");
1383
+ yield this.page.mouse.move(
1384
+ element.center[0],
1385
+ element.center[1]
1386
+ );
1387
+ })
1388
+ };
1389
+ return taskActionHover;
1390
+ }
1391
+ if (plan2.type === "Scroll") {
1392
+ const taskActionScroll = {
1393
+ type: "Action",
1394
+ subType: "Scroll",
1395
+ param: plan2.param,
1396
+ executor: (taskParam) => __async(this, null, function* () {
1397
+ const scrollToEventName = taskParam.scrollType;
1398
+ switch (scrollToEventName) {
1399
+ case "scrollUntilTop":
1400
+ yield this.page.scrollUntilTop();
1401
+ break;
1402
+ case "scrollUntilBottom":
1403
+ yield this.page.scrollUntilBottom();
1404
+ break;
1405
+ case "scrollUpOneScreen":
1406
+ yield this.page.scrollUpOneScreen();
1407
+ break;
1408
+ case "scrollDownOneScreen":
1409
+ yield this.page.scrollDownOneScreen();
1410
+ break;
1411
+ default:
1412
+ console.error(
1413
+ "Unknown scroll event type:",
1414
+ scrollToEventName
1415
+ );
1416
+ }
1417
+ })
1418
+ };
1419
+ return taskActionScroll;
1420
+ }
1421
+ if (plan2.type === "Sleep") {
1422
+ const taskActionSleep = {
1423
+ type: "Action",
1424
+ subType: "Sleep",
1425
+ param: plan2.param,
1426
+ executor: (taskParam) => __async(this, null, function* () {
1427
+ yield (0, import_utils5.sleep)(taskParam.timeMs || 3e3);
1428
+ })
1429
+ };
1430
+ return taskActionSleep;
1431
+ }
1432
+ if (plan2.type === "Error") {
1433
+ const taskActionError = {
1434
+ type: "Action",
1435
+ subType: "Error",
1436
+ param: plan2.param,
1437
+ executor: (taskParam) => __async(this, null, function* () {
1438
+ (0, import_node_assert2.default)(
1439
+ taskParam.thought,
1440
+ "An error occurred, but no thought provided"
1441
+ );
1442
+ throw new Error(taskParam.thought);
1443
+ })
1444
+ };
1445
+ return taskActionError;
1446
+ }
1447
+ throw new Error(`Unknown or Unsupported task type: ${plan2.type}`);
1448
+ }).map((task) => {
1449
+ return this.wrapExecutorWithScreenshot(task);
1450
+ });
1451
+ return tasks;
1412
1452
  });
1413
- return tasks;
1414
- }
1415
- async action(userPrompt) {
1416
- const taskExecutor = new import_core.Executor(userPrompt);
1417
- const cacheGroup = this.taskCache.getCacheGroupByPrompt(userPrompt);
1418
- let plans = [];
1419
- const planningTask = {
1420
- type: "Planning",
1421
- param: {
1422
- userPrompt
1423
- },
1424
- executor: async (param) => {
1425
- const pageContext = await this.insight.contextRetrieverFn();
1426
- let planResult;
1427
- const planCache = cacheGroup.readCache(pageContext, "plan", userPrompt);
1428
- if (planCache) {
1429
- planResult = planCache;
1430
- } else {
1431
- planResult = await (0, import_core.plan)(param.userPrompt, {
1432
- context: pageContext
1453
+ }
1454
+ action(userPrompt) {
1455
+ return __async(this, null, function* () {
1456
+ const taskExecutor = new import_core.Executor(userPrompt);
1457
+ const cacheGroup = this.taskCache.getCacheGroupByPrompt(userPrompt);
1458
+ let plans = [];
1459
+ const planningTask = {
1460
+ type: "Planning",
1461
+ param: {
1462
+ userPrompt
1463
+ },
1464
+ executor: (param) => __async(this, null, function* () {
1465
+ const pageContext = yield this.insight.contextRetrieverFn();
1466
+ let planResult;
1467
+ const planCache = cacheGroup.readCache(pageContext, "plan", userPrompt);
1468
+ if (planCache) {
1469
+ planResult = planCache;
1470
+ } else {
1471
+ planResult = yield (0, import_core.plan)(param.userPrompt, {
1472
+ context: pageContext
1473
+ });
1474
+ }
1475
+ (0, import_node_assert2.default)(planResult.plans.length > 0, "No plans found");
1476
+ plans = planResult.plans;
1477
+ cacheGroup.saveCache({
1478
+ type: "plan",
1479
+ pageContext: {
1480
+ url: pageContext.url,
1481
+ size: pageContext.size
1482
+ },
1483
+ prompt: userPrompt,
1484
+ response: planResult
1433
1485
  });
1434
- }
1435
- (0, import_node_assert2.default)(planResult.plans.length > 0, "No plans found");
1436
- plans = planResult.plans;
1437
- cacheGroup.saveCache({
1438
- type: "plan",
1439
- pageContext: {
1440
- url: pageContext.url,
1441
- size: pageContext.size
1442
- },
1443
- prompt: userPrompt,
1444
- response: planResult
1445
- });
1486
+ return {
1487
+ output: planResult,
1488
+ cache: {
1489
+ hit: Boolean(planCache)
1490
+ }
1491
+ };
1492
+ })
1493
+ };
1494
+ yield taskExecutor.append(this.wrapExecutorWithScreenshot(planningTask));
1495
+ let output = yield taskExecutor.flush();
1496
+ if (taskExecutor.isInErrorState()) {
1446
1497
  return {
1447
- output: planResult,
1448
- cache: {
1449
- hit: Boolean(planCache)
1450
- }
1498
+ output,
1499
+ executor: taskExecutor
1451
1500
  };
1452
1501
  }
1453
- };
1454
- await taskExecutor.append(this.wrapExecutorWithScreenshot(planningTask));
1455
- let output = await taskExecutor.flush();
1456
- if (taskExecutor.isInErrorState()) {
1502
+ const executables = yield this.convertPlanToExecutable(plans, cacheGroup);
1503
+ yield taskExecutor.append(executables);
1504
+ output = yield taskExecutor.flush();
1457
1505
  return {
1458
1506
  output,
1459
1507
  executor: taskExecutor
1460
1508
  };
1461
- }
1462
- const executables = await this.convertPlanToExecutable(plans, cacheGroup);
1463
- await taskExecutor.append(executables);
1464
- output = await taskExecutor.flush();
1465
- return {
1466
- output,
1467
- executor: taskExecutor
1468
- };
1469
- }
1470
- async query(demand) {
1471
- const description = typeof demand === "string" ? demand : JSON.stringify(demand);
1472
- const taskExecutor = new import_core.Executor(description);
1473
- const queryTask = {
1474
- type: "Insight",
1475
- subType: "Query",
1476
- param: {
1477
- dataDemand: demand
1478
- },
1479
- executor: async (param) => {
1480
- let insightDump;
1481
- const dumpCollector = (dump) => {
1482
- insightDump = dump;
1483
- };
1484
- this.insight.onceDumpUpdatedFn = dumpCollector;
1485
- const data = await this.insight.extract(param.dataDemand);
1486
- return {
1487
- output: data,
1488
- log: { dump: insightDump }
1489
- };
1490
- }
1491
- };
1492
- await taskExecutor.append(this.wrapExecutorWithScreenshot(queryTask));
1493
- const output = await taskExecutor.flush();
1494
- return {
1495
- output,
1496
- executor: taskExecutor
1497
- };
1509
+ });
1498
1510
  }
1499
- async assert(assertion) {
1500
- const description = `assert: ${assertion}`;
1501
- const taskExecutor = new import_core.Executor(description);
1502
- const assertionPlan = {
1503
- type: "Assert",
1504
- param: {
1505
- assertion
1506
- }
1507
- };
1508
- const assertTask = await this.convertPlanToExecutable([assertionPlan]);
1509
- await taskExecutor.append(this.wrapExecutorWithScreenshot(assertTask[0]));
1510
- const output = await taskExecutor.flush();
1511
- return {
1512
- output,
1513
- executor: taskExecutor
1514
- };
1511
+ query(demand) {
1512
+ return __async(this, null, function* () {
1513
+ const description = typeof demand === "string" ? demand : JSON.stringify(demand);
1514
+ const taskExecutor = new import_core.Executor(description);
1515
+ const queryTask = {
1516
+ type: "Insight",
1517
+ subType: "Query",
1518
+ param: {
1519
+ dataDemand: demand
1520
+ },
1521
+ executor: (param) => __async(this, null, function* () {
1522
+ let insightDump;
1523
+ const dumpCollector = (dump) => {
1524
+ insightDump = dump;
1525
+ };
1526
+ this.insight.onceDumpUpdatedFn = dumpCollector;
1527
+ const data = yield this.insight.extract(param.dataDemand);
1528
+ return {
1529
+ output: data,
1530
+ log: { dump: insightDump }
1531
+ };
1532
+ })
1533
+ };
1534
+ yield taskExecutor.append(this.wrapExecutorWithScreenshot(queryTask));
1535
+ const output = yield taskExecutor.flush();
1536
+ return {
1537
+ output,
1538
+ executor: taskExecutor
1539
+ };
1540
+ });
1515
1541
  }
1516
- async waitFor(assertion, opt) {
1517
- const description = `waitFor: ${assertion}`;
1518
- const taskExecutor = new import_core.Executor(description);
1519
- const { timeoutMs, checkIntervalMs } = opt;
1520
- (0, import_node_assert2.default)(assertion, "No assertion for waitFor");
1521
- (0, import_node_assert2.default)(timeoutMs, "No timeoutMs for waitFor");
1522
- (0, import_node_assert2.default)(checkIntervalMs, "No checkIntervalMs for waitFor");
1523
- const overallStartTime = Date.now();
1524
- let startTime = Date.now();
1525
- let errorThought = "";
1526
- while (Date.now() - overallStartTime < timeoutMs) {
1527
- startTime = Date.now();
1528
- const assertPlan = {
1529
- type: "AssertWithoutThrow",
1542
+ assert(assertion) {
1543
+ return __async(this, null, function* () {
1544
+ const description = `assert: ${assertion}`;
1545
+ const taskExecutor = new import_core.Executor(description);
1546
+ const assertionPlan = {
1547
+ type: "Assert",
1530
1548
  param: {
1531
1549
  assertion
1532
1550
  }
1533
1551
  };
1534
- const assertTask = await this.convertPlanToExecutable([assertPlan]);
1535
- await taskExecutor.append(this.wrapExecutorWithScreenshot(assertTask[0]));
1536
- const output = await taskExecutor.flush();
1537
- if (output == null ? void 0 : output.pass) {
1538
- return {
1539
- output: void 0,
1540
- executor: taskExecutor
1541
- };
1542
- }
1543
- errorThought = (output == null ? void 0 : output.thought) || "unknown error";
1544
- const now = Date.now();
1545
- if (now - startTime < checkIntervalMs) {
1546
- const timeRemaining = checkIntervalMs - (now - startTime);
1547
- const sleepPlan = {
1548
- type: "Sleep",
1552
+ const assertTask = yield this.convertPlanToExecutable([assertionPlan]);
1553
+ yield taskExecutor.append(this.wrapExecutorWithScreenshot(assertTask[0]));
1554
+ const output = yield taskExecutor.flush();
1555
+ return {
1556
+ output,
1557
+ executor: taskExecutor
1558
+ };
1559
+ });
1560
+ }
1561
+ waitFor(assertion, opt) {
1562
+ return __async(this, null, function* () {
1563
+ const description = `waitFor: ${assertion}`;
1564
+ const taskExecutor = new import_core.Executor(description);
1565
+ const { timeoutMs, checkIntervalMs } = opt;
1566
+ (0, import_node_assert2.default)(assertion, "No assertion for waitFor");
1567
+ (0, import_node_assert2.default)(timeoutMs, "No timeoutMs for waitFor");
1568
+ (0, import_node_assert2.default)(checkIntervalMs, "No checkIntervalMs for waitFor");
1569
+ const overallStartTime = Date.now();
1570
+ let startTime = Date.now();
1571
+ let errorThought = "";
1572
+ while (Date.now() - overallStartTime < timeoutMs) {
1573
+ startTime = Date.now();
1574
+ const assertPlan = {
1575
+ type: "AssertWithoutThrow",
1549
1576
  param: {
1550
- timeMs: timeRemaining
1577
+ assertion
1551
1578
  }
1552
1579
  };
1553
- const sleepTask = await this.convertPlanToExecutable([sleepPlan]);
1554
- await taskExecutor.append(
1555
- this.wrapExecutorWithScreenshot(sleepTask[0])
1556
- );
1557
- await taskExecutor.flush();
1558
- }
1559
- }
1560
- const errorPlan = {
1561
- type: "Error",
1562
- param: {
1563
- thought: `waitFor timeout: ${errorThought}`
1580
+ const assertTask = yield this.convertPlanToExecutable([assertPlan]);
1581
+ yield taskExecutor.append(this.wrapExecutorWithScreenshot(assertTask[0]));
1582
+ const output = yield taskExecutor.flush();
1583
+ if (output == null ? void 0 : output.pass) {
1584
+ return {
1585
+ output: void 0,
1586
+ executor: taskExecutor
1587
+ };
1588
+ }
1589
+ errorThought = (output == null ? void 0 : output.thought) || "unknown error";
1590
+ const now = Date.now();
1591
+ if (now - startTime < checkIntervalMs) {
1592
+ const timeRemaining = checkIntervalMs - (now - startTime);
1593
+ const sleepPlan = {
1594
+ type: "Sleep",
1595
+ param: {
1596
+ timeMs: timeRemaining
1597
+ }
1598
+ };
1599
+ const sleepTask = yield this.convertPlanToExecutable([sleepPlan]);
1600
+ yield taskExecutor.append(
1601
+ this.wrapExecutorWithScreenshot(sleepTask[0])
1602
+ );
1603
+ yield taskExecutor.flush();
1604
+ }
1564
1605
  }
1565
- };
1566
- const errorTask = await this.convertPlanToExecutable([errorPlan]);
1567
- await taskExecutor.append(errorTask[0]);
1568
- await taskExecutor.flush();
1569
- return {
1570
- output: void 0,
1571
- executor: taskExecutor
1572
- };
1606
+ const errorPlan = {
1607
+ type: "Error",
1608
+ param: {
1609
+ thought: `waitFor timeout: ${errorThought}`
1610
+ }
1611
+ };
1612
+ const errorTask = yield this.convertPlanToExecutable([errorPlan]);
1613
+ yield taskExecutor.append(errorTask[0]);
1614
+ yield taskExecutor.flush();
1615
+ return {
1616
+ output: void 0,
1617
+ executor: taskExecutor
1618
+ };
1619
+ });
1573
1620
  }
1574
1621
  };
1575
1622
 
@@ -1603,83 +1650,94 @@ var PageAgent = class {
1603
1650
  dumpDataString() {
1604
1651
  this.dump.groupName = this.opts.groupName;
1605
1652
  this.dump.groupDescription = this.opts.groupDescription;
1606
- return (0, import_utils5.stringifyDumpData)(this.dump);
1653
+ return (0, import_utils7.stringifyDumpData)(this.dump);
1607
1654
  }
1608
1655
  writeOutActionDumps() {
1609
1656
  const { generateReport, autoPrintReportMsg } = this.opts;
1610
- this.reportFile = (0, import_utils5.writeLogFile)({
1657
+ this.reportFile = (0, import_utils7.writeLogFile)({
1611
1658
  fileName: this.reportFileName,
1612
- fileExt: import_utils5.groupedActionDumpFileExt,
1659
+ fileExt: import_utils7.groupedActionDumpFileExt,
1613
1660
  fileContent: this.dumpDataString(),
1614
1661
  type: "dump",
1615
1662
  generateReport
1616
1663
  });
1617
- if (generateReport && autoPrintReportMsg) {
1664
+ if (generateReport && autoPrintReportMsg && this.reportFile) {
1618
1665
  printReportMsg(this.reportFile);
1619
1666
  }
1620
1667
  }
1621
- async aiAction(taskPrompt) {
1622
- const { executor } = await this.taskExecutor.action(taskPrompt);
1623
- this.appendExecutionDump(executor.dump());
1624
- this.writeOutActionDumps();
1625
- if (executor.isInErrorState()) {
1626
- const errorTask = executor.latestErrorTask();
1627
- throw new Error(`${errorTask == null ? void 0 : errorTask.error}
1668
+ aiAction(taskPrompt) {
1669
+ return __async(this, null, function* () {
1670
+ const { executor } = yield this.taskExecutor.action(taskPrompt);
1671
+ this.appendExecutionDump(executor.dump());
1672
+ this.writeOutActionDumps();
1673
+ if (executor.isInErrorState()) {
1674
+ const errorTask = executor.latestErrorTask();
1675
+ throw new Error(`${errorTask == null ? void 0 : errorTask.error}
1628
1676
  ${errorTask == null ? void 0 : errorTask.errorStack}`);
1629
- }
1677
+ }
1678
+ });
1630
1679
  }
1631
- async aiQuery(demand) {
1632
- const { output, executor } = await this.taskExecutor.query(demand);
1633
- this.appendExecutionDump(executor.dump());
1634
- this.writeOutActionDumps();
1635
- if (executor.isInErrorState()) {
1636
- const errorTask = executor.latestErrorTask();
1637
- throw new Error(`${errorTask == null ? void 0 : errorTask.error}
1680
+ aiQuery(demand) {
1681
+ return __async(this, null, function* () {
1682
+ const { output, executor } = yield this.taskExecutor.query(demand);
1683
+ this.appendExecutionDump(executor.dump());
1684
+ this.writeOutActionDumps();
1685
+ if (executor.isInErrorState()) {
1686
+ const errorTask = executor.latestErrorTask();
1687
+ throw new Error(`${errorTask == null ? void 0 : errorTask.error}
1638
1688
  ${errorTask == null ? void 0 : errorTask.errorStack}`);
1639
- }
1640
- return output;
1641
- }
1642
- async aiAssert(assertion, msg, opt) {
1643
- const { output, executor } = await this.taskExecutor.assert(assertion);
1644
- this.appendExecutionDump(executor.dump());
1645
- this.writeOutActionDumps();
1646
- if (opt == null ? void 0 : opt.keepRawResponse) {
1689
+ }
1647
1690
  return output;
1648
- }
1649
- if (!(output == null ? void 0 : output.pass)) {
1650
- const errMsg = msg || `Assertion failed: ${assertion}`;
1651
- const reasonMsg = `Reason: ${(output == null ? void 0 : output.thought) || "(no_reason)"}`;
1652
- throw new Error(`${errMsg}
1653
- ${reasonMsg}`);
1654
- }
1691
+ });
1655
1692
  }
1656
- async aiWaitFor(assertion, opt) {
1657
- const { executor } = await this.taskExecutor.waitFor(assertion, {
1658
- timeoutMs: (opt == null ? void 0 : opt.timeoutMs) || 15 * 1e3,
1659
- checkIntervalMs: (opt == null ? void 0 : opt.checkIntervalMs) || 3 * 1e3,
1660
- assertion
1693
+ aiAssert(assertion, msg, opt) {
1694
+ return __async(this, null, function* () {
1695
+ var _a;
1696
+ const { output, executor } = yield this.taskExecutor.assert(assertion);
1697
+ this.appendExecutionDump(executor.dump());
1698
+ this.writeOutActionDumps();
1699
+ if (opt == null ? void 0 : opt.keepRawResponse) {
1700
+ return output;
1701
+ }
1702
+ if (!(output == null ? void 0 : output.pass)) {
1703
+ const errMsg = msg || `Assertion failed: ${assertion}`;
1704
+ const reasonMsg = `Reason: ${(output == null ? void 0 : output.thought) || ((_a = executor.latestErrorTask()) == null ? void 0 : _a.error) || "(no_reason)"}`;
1705
+ throw new Error(`${errMsg}
1706
+ ${reasonMsg}`);
1707
+ }
1661
1708
  });
1662
- this.appendExecutionDump(executor.dump());
1663
- this.writeOutActionDumps();
1664
- if (executor.isInErrorState()) {
1665
- const errorTask = executor.latestErrorTask();
1666
- throw new Error(`${errorTask == null ? void 0 : errorTask.error}
1709
+ }
1710
+ aiWaitFor(assertion, opt) {
1711
+ return __async(this, null, function* () {
1712
+ const { executor } = yield this.taskExecutor.waitFor(assertion, {
1713
+ timeoutMs: (opt == null ? void 0 : opt.timeoutMs) || 15 * 1e3,
1714
+ checkIntervalMs: (opt == null ? void 0 : opt.checkIntervalMs) || 3 * 1e3,
1715
+ assertion
1716
+ });
1717
+ this.appendExecutionDump(executor.dump());
1718
+ this.writeOutActionDumps();
1719
+ if (executor.isInErrorState()) {
1720
+ const errorTask = executor.latestErrorTask();
1721
+ throw new Error(`${errorTask == null ? void 0 : errorTask.error}
1667
1722
  ${errorTask == null ? void 0 : errorTask.errorStack}`);
1668
- }
1723
+ }
1724
+ });
1669
1725
  }
1670
- async ai(taskPrompt, type = "action") {
1671
- if (type === "action") {
1672
- return this.aiAction(taskPrompt);
1673
- }
1674
- if (type === "query") {
1675
- return this.aiQuery(taskPrompt);
1676
- }
1677
- if (type === "assert") {
1678
- return this.aiAssert(taskPrompt);
1679
- }
1680
- throw new Error(
1681
- `Unknown type: ${type}, only support 'action', 'query', 'assert'`
1682
- );
1726
+ ai(taskPrompt, type = "action") {
1727
+ return __async(this, null, function* () {
1728
+ if (type === "action") {
1729
+ return this.aiAction(taskPrompt);
1730
+ }
1731
+ if (type === "query") {
1732
+ return this.aiQuery(taskPrompt);
1733
+ }
1734
+ if (type === "assert") {
1735
+ return this.aiAssert(taskPrompt);
1736
+ }
1737
+ throw new Error(
1738
+ `Unknown type: ${type}, only support 'action', 'query', 'assert'`
1739
+ );
1740
+ });
1683
1741
  }
1684
1742
  };
1685
1743
 
@@ -1708,7 +1766,7 @@ var PlaywrightAiFixture = () => {
1708
1766
  const agentForPage = (page, testInfo) => {
1709
1767
  let idForPage = page[midsceneAgentKeyId];
1710
1768
  if (!idForPage) {
1711
- idForPage = (0, import_node_crypto2.randomUUID)();
1769
+ idForPage = (0, import_node_crypto.randomUUID)();
1712
1770
  page[midsceneAgentKeyId] = idForPage;
1713
1771
  const { testId } = testInfo;
1714
1772
  const { taskFile, taskTitle } = groupAndCaseForTest(testInfo);
@@ -1737,70 +1795,94 @@ var PlaywrightAiFixture = () => {
1737
1795
  }
1738
1796
  };
1739
1797
  return {
1740
- ai: async ({ page }, use, testInfo) => {
1798
+ ai: (_0, _1, _2) => __async(void 0, [_0, _1, _2], function* ({ page }, use, testInfo) {
1741
1799
  const agent = agentForPage(page, testInfo);
1742
- await use(
1743
- async (taskPrompt, opts) => {
1800
+ yield use(
1801
+ (taskPrompt, opts) => __async(void 0, null, function* () {
1744
1802
  return new Promise((resolve, reject) => {
1745
- import_test.test.step(`ai - ${taskPrompt}`, async () => {
1746
- await waitForNetworkIdle(page);
1803
+ import_test.test.step(`ai - ${taskPrompt}`, () => __async(void 0, null, function* () {
1804
+ yield waitForNetworkIdle(page);
1747
1805
  const actionType = (opts == null ? void 0 : opts.type) || "action";
1748
- const result = await agent.ai(taskPrompt, actionType);
1749
- resolve(result);
1750
- });
1806
+ try {
1807
+ const result = yield agent.ai(taskPrompt, actionType);
1808
+ resolve(result);
1809
+ } catch (error) {
1810
+ reject(error);
1811
+ }
1812
+ }));
1751
1813
  });
1752
- }
1814
+ })
1753
1815
  );
1754
1816
  updateDumpAnnotation(testInfo, agent.dumpDataString());
1755
- },
1756
- aiAction: async ({ page }, use, testInfo) => {
1817
+ }),
1818
+ aiAction: (_0, _1, _2) => __async(void 0, [_0, _1, _2], function* ({ page }, use, testInfo) {
1757
1819
  const agent = agentForPage(page, testInfo);
1758
- await use(async (taskPrompt) => {
1759
- import_test.test.step(`aiAction - ${taskPrompt}`, async () => {
1760
- await waitForNetworkIdle(page);
1761
- await agent.aiAction(taskPrompt);
1820
+ yield use((taskPrompt) => __async(void 0, null, function* () {
1821
+ return new Promise((resolve, reject) => {
1822
+ import_test.test.step(`aiAction - ${taskPrompt}`, () => __async(void 0, null, function* () {
1823
+ yield waitForNetworkIdle(page);
1824
+ try {
1825
+ const result = yield agent.aiAction(taskPrompt);
1826
+ resolve(result);
1827
+ } catch (error) {
1828
+ reject(error);
1829
+ }
1830
+ }));
1762
1831
  });
1763
- });
1832
+ }));
1764
1833
  updateDumpAnnotation(testInfo, agent.dumpDataString());
1765
- },
1766
- aiQuery: async ({ page }, use, testInfo) => {
1834
+ }),
1835
+ aiQuery: (_0, _1, _2) => __async(void 0, [_0, _1, _2], function* ({ page }, use, testInfo) {
1767
1836
  const agent = agentForPage(page, testInfo);
1768
- await use(async (demand) => {
1837
+ yield use((demand) => __async(void 0, null, function* () {
1769
1838
  return new Promise((resolve, reject) => {
1770
- import_test.test.step(`aiQuery - ${JSON.stringify(demand)}`, async () => {
1771
- await waitForNetworkIdle(page);
1772
- const result = await agent.aiQuery(demand);
1773
- resolve(result);
1774
- });
1839
+ import_test.test.step(`aiQuery - ${JSON.stringify(demand)}`, () => __async(void 0, null, function* () {
1840
+ yield waitForNetworkIdle(page);
1841
+ try {
1842
+ const result = yield agent.aiQuery(demand);
1843
+ resolve(result);
1844
+ } catch (error) {
1845
+ reject(error);
1846
+ }
1847
+ }));
1775
1848
  });
1776
- });
1849
+ }));
1777
1850
  updateDumpAnnotation(testInfo, agent.dumpDataString());
1778
- },
1779
- aiAssert: async ({ page }, use, testInfo) => {
1851
+ }),
1852
+ aiAssert: (_0, _1, _2) => __async(void 0, [_0, _1, _2], function* ({ page }, use, testInfo) {
1780
1853
  const agent = agentForPage(page, testInfo);
1781
- await use(async (assertion, errorMsg) => {
1854
+ yield use((assertion, errorMsg) => __async(void 0, null, function* () {
1782
1855
  return new Promise((resolve, reject) => {
1783
- import_test.test.step(`aiAssert - ${assertion}`, async () => {
1784
- await waitForNetworkIdle(page);
1785
- await agent.aiAssert(assertion, errorMsg);
1786
- resolve(null);
1787
- });
1856
+ import_test.test.step(`aiAssert - ${assertion}`, () => __async(void 0, null, function* () {
1857
+ yield waitForNetworkIdle(page);
1858
+ try {
1859
+ yield agent.aiAssert(assertion, errorMsg);
1860
+ resolve(null);
1861
+ } catch (error) {
1862
+ reject(error);
1863
+ }
1864
+ }));
1788
1865
  });
1789
- });
1866
+ }));
1790
1867
  updateDumpAnnotation(testInfo, agent.dumpDataString());
1791
- },
1792
- aiWaitFor: async ({ page }, use, testInfo) => {
1868
+ }),
1869
+ aiWaitFor: (_0, _1, _2) => __async(void 0, [_0, _1, _2], function* ({ page }, use, testInfo) {
1793
1870
  const agent = agentForPage(page, testInfo);
1794
- await use(async (assertion, opt) => {
1871
+ yield use((assertion, opt) => __async(void 0, null, function* () {
1795
1872
  return new Promise((resolve, reject) => {
1796
- import_test.test.step(`aiWaitFor - ${assertion}`, async () => {
1797
- await agent.aiWaitFor(assertion, opt);
1798
- resolve(null);
1799
- });
1873
+ import_test.test.step(`aiWaitFor - ${assertion}`, () => __async(void 0, null, function* () {
1874
+ yield waitForNetworkIdle(page);
1875
+ try {
1876
+ yield agent.aiWaitFor(assertion, opt);
1877
+ resolve(null);
1878
+ } catch (error) {
1879
+ reject(error);
1880
+ }
1881
+ }));
1800
1882
  });
1801
- });
1883
+ }));
1802
1884
  updateDumpAnnotation(testInfo, agent.dumpDataString());
1803
- }
1885
+ })
1804
1886
  };
1805
1887
  };
1806
1888
  function waitForNetworkIdle(page) {
@@ -1813,87 +1895,113 @@ function waitForNetworkIdle(page) {
1813
1895
 
1814
1896
  // src/puppeteer/base-page.ts
1815
1897
  var import_node_fs3 = require("fs");
1816
- var import_utils7 = require("@midscene/core/utils");
1817
- var import_img4 = require("@midscene/shared/img");
1898
+ var import_utils9 = require("@midscene/core/utils");
1899
+ var import_img3 = require("@midscene/shared/img");
1818
1900
  var Page = class {
1819
1901
  evaluate(pageFunction, arg) {
1820
1902
  if (this.pageType === "puppeteer") {
1821
- return this.page.evaluate(pageFunction, arg);
1903
+ return this.underlyingPage.evaluate(pageFunction, arg);
1822
1904
  }
1823
- return this.page.evaluate(pageFunction, arg);
1905
+ return this.underlyingPage.evaluate(pageFunction, arg);
1824
1906
  }
1825
- constructor(page, pageType) {
1826
- this.page = page;
1907
+ constructor(underlyingPage, pageType) {
1908
+ this.underlyingPage = underlyingPage;
1827
1909
  this.pageType = pageType;
1828
1910
  }
1829
- async getElementInfos() {
1830
- const scripts = await getExtraReturnLogic();
1831
- const captureElementSnapshot = await this.evaluate(scripts);
1832
- return captureElementSnapshot;
1833
- }
1834
- async screenshot() {
1835
- const viewportSize = await this.evaluate(() => {
1836
- return {
1837
- width: document.documentElement.clientWidth,
1838
- height: document.documentElement.clientHeight,
1839
- deviceScaleFactor: window.devicePixelRatio
1840
- };
1841
- });
1842
- const path3 = (0, import_utils7.getTmpFile)("png");
1843
- await this.page.screenshot({
1844
- path: path3,
1845
- type: "png"
1911
+ getElementInfos() {
1912
+ return __async(this, null, function* () {
1913
+ const scripts = yield getExtraReturnLogic();
1914
+ const captureElementSnapshot = yield this.evaluate(scripts);
1915
+ return captureElementSnapshot;
1846
1916
  });
1847
- let buf;
1848
- if (viewportSize.deviceScaleFactor > 1) {
1849
- buf = await (0, import_img4.resizeImg)((0, import_node_fs3.readFileSync)(path3), {
1850
- width: viewportSize.width,
1851
- height: viewportSize.height
1917
+ }
1918
+ screenshotBase64() {
1919
+ return __async(this, null, function* () {
1920
+ const viewportSize = yield this.evaluate(() => {
1921
+ return {
1922
+ width: document.documentElement.clientWidth,
1923
+ height: document.documentElement.clientHeight,
1924
+ deviceScaleFactor: window.devicePixelRatio
1925
+ };
1852
1926
  });
1853
- (0, import_node_fs3.writeFileSync)(path3, buf);
1854
- }
1855
- return path3;
1927
+ const path3 = (0, import_utils9.getTmpFile)("png");
1928
+ yield this.underlyingPage.screenshot({
1929
+ path: path3,
1930
+ type: "png"
1931
+ });
1932
+ let buf;
1933
+ if (viewportSize.deviceScaleFactor > 1) {
1934
+ buf = yield (0, import_img3.resizeImg)((0, import_node_fs3.readFileSync)(path3), {
1935
+ width: viewportSize.width,
1936
+ height: viewportSize.height
1937
+ });
1938
+ (0, import_node_fs3.writeFileSync)(path3, buf);
1939
+ }
1940
+ return (0, import_img3.base64Encoded)(path3, true);
1941
+ });
1856
1942
  }
1857
1943
  url() {
1858
- return this.page.url();
1944
+ return this.underlyingPage.url();
1859
1945
  }
1860
1946
  get mouse() {
1861
1947
  return {
1862
- click: async (x, y, options) => this.page.mouse.click(x, y, { button: (options == null ? void 0 : options.button) || "left" }),
1863
- wheel: async (deltaX, deltaY) => {
1948
+ click: (x, y, options) => __async(this, null, function* () {
1949
+ return this.underlyingPage.mouse.click(x, y, {
1950
+ button: (options == null ? void 0 : options.button) || "left"
1951
+ });
1952
+ }),
1953
+ wheel: (deltaX, deltaY) => __async(this, null, function* () {
1864
1954
  if (this.pageType === "puppeteer") {
1865
- await this.page.mouse.wheel({ deltaX, deltaY });
1955
+ yield this.underlyingPage.mouse.wheel({
1956
+ deltaX,
1957
+ deltaY
1958
+ });
1866
1959
  } else if (this.pageType === "playwright") {
1867
- await this.page.mouse.wheel(deltaX, deltaY);
1960
+ yield this.underlyingPage.mouse.wheel(
1961
+ deltaX,
1962
+ deltaY
1963
+ );
1868
1964
  }
1869
- },
1870
- move: async (x, y) => this.page.mouse.move(x, y)
1965
+ }),
1966
+ move: (x, y) => __async(this, null, function* () {
1967
+ return this.underlyingPage.mouse.move(x, y);
1968
+ })
1871
1969
  };
1872
1970
  }
1873
1971
  get keyboard() {
1874
1972
  return {
1875
- type: async (text) => this.page.keyboard.type(text),
1876
- press: async (key) => this.page.keyboard.press(key),
1877
- down: async (key) => this.page.keyboard.down(key),
1878
- up: async (key) => this.page.keyboard.up(key)
1973
+ type: (text) => __async(this, null, function* () {
1974
+ return this.underlyingPage.keyboard.type(text);
1975
+ }),
1976
+ press: (key) => __async(this, null, function* () {
1977
+ return this.underlyingPage.keyboard.press(key);
1978
+ }),
1979
+ down: (key) => __async(this, null, function* () {
1980
+ return this.underlyingPage.keyboard.down(key);
1981
+ }),
1982
+ up: (key) => __async(this, null, function* () {
1983
+ return this.underlyingPage.keyboard.up(key);
1984
+ })
1879
1985
  };
1880
1986
  }
1881
- async clearInput(element) {
1882
- if (!element) {
1883
- return;
1884
- }
1885
- await this.mouse.click(element.center[0], element.center[1]);
1886
- const isMac = process.platform === "darwin";
1887
- if (isMac) {
1888
- await this.page.keyboard.down("Meta");
1889
- await this.page.keyboard.press("a");
1890
- await this.page.keyboard.up("Meta");
1891
- } else {
1892
- await this.page.keyboard.down("Control");
1893
- await this.page.keyboard.press("a");
1894
- await this.page.keyboard.up("Control");
1895
- }
1896
- await this.keyboard.press("Backspace");
1987
+ clearInput(element) {
1988
+ return __async(this, null, function* () {
1989
+ if (!element) {
1990
+ return;
1991
+ }
1992
+ yield this.mouse.click(element.center[0], element.center[1]);
1993
+ const isMac = process.platform === "darwin";
1994
+ if (isMac) {
1995
+ yield this.underlyingPage.keyboard.down("Meta");
1996
+ yield this.underlyingPage.keyboard.press("a");
1997
+ yield this.underlyingPage.keyboard.up("Meta");
1998
+ } else {
1999
+ yield this.underlyingPage.keyboard.down("Control");
2000
+ yield this.underlyingPage.keyboard.press("a");
2001
+ yield this.underlyingPage.keyboard.up("Control");
2002
+ }
2003
+ yield this.keyboard.press("Backspace");
2004
+ });
1897
2005
  }
1898
2006
  scrollUntilTop() {
1899
2007
  return this.mouse.wheel(0, -9999999);
@@ -1901,15 +2009,19 @@ var Page = class {
1901
2009
  scrollUntilBottom() {
1902
2010
  return this.mouse.wheel(0, 9999999);
1903
2011
  }
1904
- async scrollUpOneScreen() {
1905
- const innerHeight = await this.evaluate(() => window.innerHeight);
1906
- const distance = innerHeight * 0.7;
1907
- await this.mouse.wheel(0, -distance);
2012
+ scrollUpOneScreen() {
2013
+ return __async(this, null, function* () {
2014
+ const innerHeight = yield this.evaluate(() => window.innerHeight);
2015
+ const distance = innerHeight * 0.7;
2016
+ yield this.mouse.wheel(0, -distance);
2017
+ });
1908
2018
  }
1909
- async scrollDownOneScreen() {
1910
- const innerHeight = await this.evaluate(() => window.innerHeight);
1911
- const distance = innerHeight * 0.7;
1912
- await this.mouse.wheel(0, distance);
2019
+ scrollDownOneScreen() {
2020
+ return __async(this, null, function* () {
2021
+ const innerHeight = yield this.evaluate(() => window.innerHeight);
2022
+ const distance = innerHeight * 0.7;
2023
+ yield this.mouse.wheel(0, distance);
2024
+ });
1913
2025
  }
1914
2026
  };
1915
2027
 
@@ -1937,8 +2049,8 @@ var PuppeteerAgent = class extends PageAgent {
1937
2049
 
1938
2050
  // src/appium/page.ts
1939
2051
  var import_node_fs4 = __toESM(require("fs"));
1940
- var import_utils9 = require("@midscene/core/utils");
1941
- var import_img5 = require("@midscene/shared/img");
2052
+ var import_utils11 = require("@midscene/core/utils");
2053
+ var import_img4 = require("@midscene/shared/img");
1942
2054
  var import_xmldom = require("@xmldom/xmldom");
1943
2055
 
1944
2056
  // src/extractor/web-extractor.ts
@@ -2133,26 +2245,30 @@ var Page2 = class {
2133
2245
  this.pageType = "appium";
2134
2246
  this.browser = browser;
2135
2247
  }
2136
- async getElementInfos() {
2137
- const pageSource = await this.browser.getPageSource();
2138
- const { width, height } = await this.browser.getWindowSize();
2139
- const parser = new import_xmldom.DOMParser();
2140
- const doc = parser.parseFromString(pageSource, "text/xml");
2141
- const infos = extractTextWithPosition2(doc).filter(
2142
- (element) => element.rect.height !== height && element.rect.width !== width && element.rect.left !== 0 && element.rect.top !== 0 && element.attributes.visible === "true"
2143
- );
2144
- return infos;
2145
- }
2146
- async screenshot() {
2147
- const { width, height } = await this.browser.getWindowSize();
2148
- const path3 = (0, import_utils9.getTmpFile)("png");
2149
- const screenshotBuffer = await this.browser.saveScreenshot(path3);
2150
- const resizedScreenshotBuffer = await (0, import_img5.resizeImg)(screenshotBuffer, {
2151
- width,
2152
- height
2248
+ getElementInfos() {
2249
+ return __async(this, null, function* () {
2250
+ const pageSource = yield this.browser.getPageSource();
2251
+ const { width, height } = yield this.browser.getWindowSize();
2252
+ const parser = new import_xmldom.DOMParser();
2253
+ const doc = parser.parseFromString(pageSource, "text/xml");
2254
+ const infos = extractTextWithPosition2(doc).filter(
2255
+ (element) => element.rect.height !== height && element.rect.width !== width && element.rect.left !== 0 && element.rect.top !== 0 && element.attributes.visible === "true"
2256
+ );
2257
+ return infos;
2258
+ });
2259
+ }
2260
+ screenshotBase64() {
2261
+ return __async(this, null, function* () {
2262
+ const { width, height } = yield this.browser.getWindowSize();
2263
+ const path3 = (0, import_utils11.getTmpFile)("png");
2264
+ const screenshotBuffer = yield this.browser.saveScreenshot(path3);
2265
+ const resizedScreenshotBuffer = yield (0, import_img4.resizeImg)(screenshotBuffer, {
2266
+ width,
2267
+ height
2268
+ });
2269
+ import_node_fs4.default.writeFileSync(path3, resizedScreenshotBuffer);
2270
+ return (0, import_img4.base64Encoded)(path3);
2153
2271
  });
2154
- import_node_fs4.default.writeFileSync(path3, resizedScreenshotBuffer);
2155
- return path3;
2156
2272
  }
2157
2273
  get mouse() {
2158
2274
  return {
@@ -2168,14 +2284,16 @@ var Page2 = class {
2168
2284
  press: (key) => this.keyboardPress(key)
2169
2285
  };
2170
2286
  }
2171
- async clearInput(element) {
2172
- if (!element) {
2173
- return;
2174
- }
2175
- const ele = await this.browser.$(element.locator);
2176
- const blank = " ";
2177
- await this.keyboardType(blank);
2178
- await ele.clearValue();
2287
+ clearInput(element) {
2288
+ return __async(this, null, function* () {
2289
+ if (!element) {
2290
+ return;
2291
+ }
2292
+ const ele = yield this.browser.$(element.locator);
2293
+ const blank = " ";
2294
+ yield this.keyboardType(blank);
2295
+ yield ele.clearValue();
2296
+ });
2179
2297
  }
2180
2298
  url() {
2181
2299
  var _a;
@@ -2191,182 +2309,207 @@ var Page2 = class {
2191
2309
  return "";
2192
2310
  }
2193
2311
  // Scroll to top element
2194
- async scrollUntilTop() {
2195
- const { height } = await this.browser.getWindowSize();
2196
- await this.mouseWheel(0, height, 100);
2312
+ scrollUntilTop() {
2313
+ return __async(this, null, function* () {
2314
+ const { height } = yield this.browser.getWindowSize();
2315
+ yield this.mouseWheel(0, height, 100);
2316
+ });
2197
2317
  }
2198
2318
  // Scroll to bottom element
2199
- async scrollUntilBottom() {
2200
- const { height } = await this.browser.getWindowSize();
2201
- await this.mouseWheel(0, -height, 100);
2319
+ scrollUntilBottom() {
2320
+ return __async(this, null, function* () {
2321
+ const { height } = yield this.browser.getWindowSize();
2322
+ yield this.mouseWheel(0, -height, 100);
2323
+ });
2202
2324
  }
2203
2325
  // Scroll up one screen
2204
- async scrollUpOneScreen() {
2205
- const { height } = await this.browser.getWindowSize();
2206
- await this.mouseWheel(0, height, 1e3);
2326
+ scrollUpOneScreen() {
2327
+ return __async(this, null, function* () {
2328
+ const { height } = yield this.browser.getWindowSize();
2329
+ yield this.mouseWheel(0, height, 1e3);
2330
+ });
2207
2331
  }
2208
2332
  // Scroll down one screen
2209
- async scrollDownOneScreen() {
2210
- const { height } = await this.browser.getWindowSize();
2211
- await this.mouseWheel(0, -height, 1e3);
2212
- }
2213
- async keyboardType(text) {
2214
- const actions = [];
2215
- for (const char of text) {
2216
- actions.push({ type: "keyDown", value: char });
2217
- actions.push({ type: "keyUp", value: char });
2218
- }
2219
- if (!actions.length) {
2220
- return;
2221
- }
2222
- await this.browser.performActions([
2223
- {
2224
- type: "key",
2225
- id: "keyboard",
2226
- actions
2227
- }
2228
- ]);
2229
- }
2230
- async keyboardPress(key) {
2231
- await this.browser.performActions([
2232
- {
2233
- type: "key",
2234
- id: "keyboard",
2235
- actions: [
2236
- { type: "keyDown", value: key },
2237
- { type: "keyUp", value: key }
2238
- ]
2239
- }
2240
- ]);
2241
- }
2242
- async mouseClick(x, y, button = "left") {
2243
- await this.mouseMove(x, y);
2244
- await this.browser.performActions([
2245
- {
2246
- type: "pointer",
2247
- id: "mouse",
2248
- parameters: { pointerType: "mouse" },
2249
- actions: [
2250
- { type: "pointerMove", duration: 0, x, y },
2251
- { type: "pointerDown", button: buttonToNumber(button) },
2252
- { type: "pause", duration: 100 },
2253
- { type: "pointerUp", button: buttonToNumber(button) }
2254
- ]
2255
- }
2256
- ]);
2333
+ scrollDownOneScreen() {
2334
+ return __async(this, null, function* () {
2335
+ const { height } = yield this.browser.getWindowSize();
2336
+ yield this.mouseWheel(0, -height, 1e3);
2337
+ });
2257
2338
  }
2258
- async mouseMove(x, y) {
2259
- await this.browser.performActions([
2260
- {
2261
- type: "pointer",
2262
- id: "mouse",
2263
- parameters: { pointerType: "mouse" },
2264
- actions: [{ type: "pointerMove", duration: 0, x, y }]
2339
+ keyboardType(text) {
2340
+ return __async(this, null, function* () {
2341
+ const actions = [];
2342
+ for (const char of text) {
2343
+ actions.push({ type: "keyDown", value: char });
2344
+ actions.push({ type: "keyUp", value: char });
2265
2345
  }
2266
- ]);
2267
- }
2268
- async mouseWheel(deltaX, deltaY, duration = 1e3) {
2269
- const n = 4;
2270
- const windowSize = await this.browser.getWindowSize();
2271
- const startX = deltaX < 0 ? (n - 1) * (windowSize.width / n) : windowSize.width / n;
2272
- const startY = deltaY < 0 ? (n - 1) * (windowSize.height / n) : windowSize.height / n;
2273
- const maxNegativeDeltaX = startX;
2274
- const maxPositiveDeltaX = (n - 1) * (windowSize.width / n);
2275
- const maxNegativeDeltaY = startY;
2276
- const maxPositiveDeltaY = (n - 1) * (windowSize.height / n);
2277
- deltaX = Math.max(-maxNegativeDeltaX, Math.min(deltaX, maxPositiveDeltaX));
2278
- deltaY = Math.max(-maxNegativeDeltaY, Math.min(deltaY, maxPositiveDeltaY));
2279
- await this.browser.performActions([
2280
- {
2281
- type: "pointer",
2282
- id: "finger1",
2283
- parameters: { pointerType: "touch" },
2284
- actions: [
2285
- { type: "pointerMove", duration: 0, x: startX, y: startY },
2286
- { type: "pointerDown", button: 0 },
2287
- { type: "pause", duration },
2288
- {
2289
- type: "pointerMove",
2290
- duration,
2291
- origin: "pointer",
2292
- // Use 'pointer' as the starting point
2293
- x: deltaX,
2294
- // X offset relative to the starting point
2295
- y: deltaY
2296
- // Y offset relative to the starting point
2297
- },
2298
- { type: "pointerUp", button: 0 }
2299
- ]
2346
+ if (!actions.length) {
2347
+ return;
2300
2348
  }
2301
- ]);
2302
- }
2303
- };
2304
-
2305
- // src/debug/index.ts
2306
- var import_node_fs5 = require("fs");
2307
- var import_node_path3 = __toESM(require("path"));
2308
- var import_img6 = require("@midscene/shared/img");
2309
- async function generateExtractData(page, targetDir, saveImgType) {
2310
- const file = await page.screenshot();
2311
- const screenshotBuffer = (0, import_node_fs5.readFileSync)(file);
2312
- const inputImgBase64 = screenshotBuffer.toString("base64");
2313
- const {
2314
- elementsPositionInfo,
2315
- captureElementSnapshot,
2316
- elementsPositionInfoWithoutText
2317
- } = await getElementInfos(page);
2318
- const inputImagePath = import_node_path3.default.join(targetDir, "input.png");
2319
- const outputImagePath = import_node_path3.default.join(targetDir, "output.png");
2320
- const outputWithoutTextImgPath = import_node_path3.default.join(
2321
- targetDir,
2322
- "output_without_text.png"
2323
- );
2324
- const resizeOutputImgPath = import_node_path3.default.join(targetDir, "resize-output.png");
2325
- const snapshotJsonPath = import_node_path3.default.join(targetDir, "element-snapshot.json");
2326
- const {
2327
- compositeElementInfoImgBase64,
2328
- compositeElementInfoImgWithoutTextBase64
2329
- } = await (0, import_img6.processImageElementInfo)({
2330
- elementsPositionInfo,
2331
- elementsPositionInfoWithoutText,
2332
- inputImgBase64
2333
- });
2334
- const resizeImgBase64 = await (0, import_img6.resizeImg)(inputImgBase64);
2335
- const existingSnapshot = (0, import_node_fs5.existsSync)(snapshotJsonPath) ? JSON.parse((0, import_node_fs5.readFileSync)(snapshotJsonPath, "utf-8")) : null;
2336
- if (existingSnapshot && JSON.stringify(existingSnapshot) === JSON.stringify(captureElementSnapshot)) {
2337
- console.log("skip save snapshot for ", targetDir);
2338
- return;
2339
- }
2340
- if (!(saveImgType == null ? void 0 : saveImgType.disableSnapshot)) {
2341
- writeFileSyncWithDir(
2342
- snapshotJsonPath,
2343
- JSON.stringify(captureElementSnapshot, null, 2)
2344
- );
2349
+ yield this.browser.performActions([
2350
+ {
2351
+ type: "key",
2352
+ id: "keyboard",
2353
+ actions
2354
+ }
2355
+ ]);
2356
+ });
2345
2357
  }
2346
- if (!(saveImgType == null ? void 0 : saveImgType.disableInputImage)) {
2347
- await (0, import_img6.saveBase64Image)({
2348
- base64Data: inputImgBase64,
2349
- outputPath: inputImagePath
2358
+ keyboardPress(key) {
2359
+ return __async(this, null, function* () {
2360
+ yield this.browser.performActions([
2361
+ {
2362
+ type: "key",
2363
+ id: "keyboard",
2364
+ actions: [
2365
+ { type: "keyDown", value: key },
2366
+ { type: "keyUp", value: key }
2367
+ ]
2368
+ }
2369
+ ]);
2350
2370
  });
2351
2371
  }
2352
- if (!(saveImgType == null ? void 0 : saveImgType.disableOutputImage)) {
2353
- await (0, import_img6.saveBase64Image)({
2354
- base64Data: compositeElementInfoImgBase64,
2355
- outputPath: outputImagePath
2372
+ mouseClick(x, y, button = "left") {
2373
+ return __async(this, null, function* () {
2374
+ yield this.mouseMove(x, y);
2375
+ yield this.browser.performActions([
2376
+ {
2377
+ type: "pointer",
2378
+ id: "mouse",
2379
+ parameters: { pointerType: "mouse" },
2380
+ actions: [
2381
+ { type: "pointerMove", duration: 0, x, y },
2382
+ { type: "pointerDown", button: buttonToNumber(button) },
2383
+ { type: "pause", duration: 100 },
2384
+ { type: "pointerUp", button: buttonToNumber(button) }
2385
+ ]
2386
+ }
2387
+ ]);
2356
2388
  });
2357
2389
  }
2358
- if (!(saveImgType == null ? void 0 : saveImgType.disableOutputWithoutTextImg)) {
2359
- await (0, import_img6.saveBase64Image)({
2360
- base64Data: compositeElementInfoImgWithoutTextBase64,
2361
- outputPath: outputWithoutTextImgPath
2390
+ mouseMove(x, y) {
2391
+ return __async(this, null, function* () {
2392
+ yield this.browser.performActions([
2393
+ {
2394
+ type: "pointer",
2395
+ id: "mouse",
2396
+ parameters: { pointerType: "mouse" },
2397
+ actions: [{ type: "pointerMove", duration: 0, x, y }]
2398
+ }
2399
+ ]);
2362
2400
  });
2363
2401
  }
2364
- if (!(saveImgType == null ? void 0 : saveImgType.disableResizeOutputImg)) {
2365
- await (0, import_img6.saveBase64Image)({
2366
- base64Data: resizeImgBase64,
2367
- outputPath: resizeOutputImgPath
2402
+ mouseWheel(deltaX, deltaY, duration = 1e3) {
2403
+ return __async(this, null, function* () {
2404
+ const n = 4;
2405
+ const windowSize = yield this.browser.getWindowSize();
2406
+ const startX = deltaX < 0 ? (n - 1) * (windowSize.width / n) : windowSize.width / n;
2407
+ const startY = deltaY < 0 ? (n - 1) * (windowSize.height / n) : windowSize.height / n;
2408
+ const maxNegativeDeltaX = startX;
2409
+ const maxPositiveDeltaX = (n - 1) * (windowSize.width / n);
2410
+ const maxNegativeDeltaY = startY;
2411
+ const maxPositiveDeltaY = (n - 1) * (windowSize.height / n);
2412
+ deltaX = Math.max(-maxNegativeDeltaX, Math.min(deltaX, maxPositiveDeltaX));
2413
+ deltaY = Math.max(-maxNegativeDeltaY, Math.min(deltaY, maxPositiveDeltaY));
2414
+ yield this.browser.performActions([
2415
+ {
2416
+ type: "pointer",
2417
+ id: "finger1",
2418
+ parameters: { pointerType: "touch" },
2419
+ actions: [
2420
+ { type: "pointerMove", duration: 0, x: startX, y: startY },
2421
+ { type: "pointerDown", button: 0 },
2422
+ { type: "pause", duration },
2423
+ {
2424
+ type: "pointerMove",
2425
+ duration,
2426
+ origin: "pointer",
2427
+ // Use 'pointer' as the starting point
2428
+ x: deltaX,
2429
+ // X offset relative to the starting point
2430
+ y: deltaY
2431
+ // Y offset relative to the starting point
2432
+ },
2433
+ { type: "pointerUp", button: 0 }
2434
+ ]
2435
+ }
2436
+ ]);
2368
2437
  });
2369
2438
  }
2439
+ };
2440
+
2441
+ // src/playground/agent.ts
2442
+ var StaticPageAgent = class extends PageAgent {
2443
+ constructor(page) {
2444
+ super(page, {});
2445
+ }
2446
+ };
2447
+
2448
+ // src/debug/index.ts
2449
+ var import_node_fs5 = require("fs");
2450
+ var import_node_path3 = __toESM(require("path"));
2451
+ var import_img5 = require("@midscene/shared/img");
2452
+ function generateExtractData(page, targetDir, saveImgType) {
2453
+ return __async(this, null, function* () {
2454
+ const inputImgBase64 = yield page.screenshotBase64();
2455
+ const {
2456
+ elementsPositionInfo,
2457
+ captureElementSnapshot,
2458
+ elementsPositionInfoWithoutText
2459
+ } = yield getElementInfos(page);
2460
+ const inputImagePath = import_node_path3.default.join(targetDir, "input.png");
2461
+ const outputImagePath = import_node_path3.default.join(targetDir, "output.png");
2462
+ const outputWithoutTextImgPath = import_node_path3.default.join(
2463
+ targetDir,
2464
+ "output_without_text.png"
2465
+ );
2466
+ const resizeOutputImgPath = import_node_path3.default.join(targetDir, "resize-output.png");
2467
+ const snapshotJsonPath = import_node_path3.default.join(targetDir, "element-snapshot.json");
2468
+ const {
2469
+ compositeElementInfoImgBase64,
2470
+ compositeElementInfoImgWithoutTextBase64
2471
+ } = yield (0, import_img5.processImageElementInfo)({
2472
+ elementsPositionInfo,
2473
+ elementsPositionInfoWithoutText,
2474
+ inputImgBase64
2475
+ });
2476
+ const resizeImgBase64 = yield (0, import_img5.resizeImg)(inputImgBase64);
2477
+ const existingSnapshot = (0, import_node_fs5.existsSync)(snapshotJsonPath) ? JSON.parse((0, import_node_fs5.readFileSync)(snapshotJsonPath, "utf-8")) : null;
2478
+ if (existingSnapshot && JSON.stringify(existingSnapshot) === JSON.stringify(captureElementSnapshot)) {
2479
+ console.log("skip save snapshot for ", targetDir);
2480
+ return;
2481
+ }
2482
+ if (!(saveImgType == null ? void 0 : saveImgType.disableSnapshot)) {
2483
+ writeFileSyncWithDir(
2484
+ snapshotJsonPath,
2485
+ JSON.stringify(captureElementSnapshot, null, 2)
2486
+ );
2487
+ }
2488
+ if (!(saveImgType == null ? void 0 : saveImgType.disableInputImage)) {
2489
+ yield (0, import_img5.saveBase64Image)({
2490
+ base64Data: inputImgBase64,
2491
+ outputPath: inputImagePath
2492
+ });
2493
+ }
2494
+ if (!(saveImgType == null ? void 0 : saveImgType.disableOutputImage)) {
2495
+ yield (0, import_img5.saveBase64Image)({
2496
+ base64Data: compositeElementInfoImgBase64,
2497
+ outputPath: outputImagePath
2498
+ });
2499
+ }
2500
+ if (!(saveImgType == null ? void 0 : saveImgType.disableOutputWithoutTextImg)) {
2501
+ yield (0, import_img5.saveBase64Image)({
2502
+ base64Data: compositeElementInfoImgWithoutTextBase64,
2503
+ outputPath: outputWithoutTextImgPath
2504
+ });
2505
+ }
2506
+ if (!(saveImgType == null ? void 0 : saveImgType.disableResizeOutputImg)) {
2507
+ yield (0, import_img5.saveBase64Image)({
2508
+ base64Data: resizeImgBase64,
2509
+ outputPath: resizeOutputImgPath
2510
+ });
2511
+ }
2512
+ });
2370
2513
  }
2371
2514
  function ensureDirectoryExistence(filePath) {
2372
2515
  const dirname = import_node_path3.default.dirname(filePath);
@@ -2380,21 +2523,23 @@ function writeFileSyncWithDir(filePath, content, options = {}) {
2380
2523
  ensureDirectoryExistence(filePath);
2381
2524
  (0, import_node_fs5.writeFileSync)(filePath, content, options);
2382
2525
  }
2383
- async function getElementInfos(page) {
2384
- const captureElementSnapshot = await page.getElementInfos();
2385
- const elementsPositionInfoWithoutText = captureElementSnapshot.filter(
2386
- (elementInfo) => {
2387
- if (elementInfo.attributes.nodeType === import_constants3.NodeType.TEXT) {
2388
- return false;
2526
+ function getElementInfos(page) {
2527
+ return __async(this, null, function* () {
2528
+ const captureElementSnapshot = yield page.getElementInfos();
2529
+ const elementsPositionInfoWithoutText = captureElementSnapshot.filter(
2530
+ (elementInfo) => {
2531
+ if (elementInfo.attributes.nodeType === import_constants3.NodeType.TEXT) {
2532
+ return false;
2533
+ }
2534
+ return true;
2389
2535
  }
2390
- return true;
2391
- }
2392
- );
2393
- return {
2394
- elementsPositionInfo: captureElementSnapshot,
2395
- captureElementSnapshot,
2396
- elementsPositionInfoWithoutText
2397
- };
2536
+ );
2537
+ return {
2538
+ elementsPositionInfo: captureElementSnapshot,
2539
+ captureElementSnapshot,
2540
+ elementsPositionInfoWithoutText
2541
+ };
2542
+ });
2398
2543
  }
2399
2544
  // Annotate the CommonJS export names for ESM import in node:
2400
2545
  0 && (module.exports = {
@@ -2403,6 +2548,7 @@ async function getElementInfos(page) {
2403
2548
  PlaywrightAgent,
2404
2549
  PlaywrightAiFixture,
2405
2550
  PuppeteerAgent,
2551
+ StaticPageAgent,
2406
2552
  generateExtractData
2407
2553
  });
2408
2554
  /*! Bundled license information: