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