@midscene/android 1.8.0 → 1.8.1

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
@@ -621,103 +621,30 @@ var __webpack_exports__ = {};
621
621
  }
622
622
  class AndroidDevice {
623
623
  actionSpace() {
624
- const defaultActions = [
625
- (0, device_namespaceObject.defineActionTap)(async (param)=>{
626
- const element = param.locate;
627
- external_node_assert_default()(element, 'Element not found, cannot tap');
628
- await this.mouseClick(element.center[0], element.center[1]);
629
- }),
630
- (0, device_namespaceObject.defineActionDoubleClick)(async (param)=>{
631
- const element = param.locate;
632
- external_node_assert_default()(element, 'Element not found, cannot double click');
633
- await this.mouseDoubleClick(element.center[0], element.center[1]);
634
- }),
635
- (0, device_namespaceObject.defineAction)({
636
- name: 'Input',
637
- description: 'Input text into the input field',
638
- interfaceAlias: 'aiInput',
639
- paramSchema: core_namespaceObject.z.object({
640
- value: core_namespaceObject.z.string().describe('The text to input. Provide the final content for replace/append modes, or an empty string when using clear mode to remove existing text.'),
641
- autoDismissKeyboard: core_namespaceObject.z.boolean().optional().describe('If true, the keyboard will be dismissed after the input is completed. Do not set it unless the user asks you to do so.'),
642
- mode: core_namespaceObject.z.preprocess((val)=>'append' === val ? 'typeOnly' : val, core_namespaceObject.z["enum"]([
643
- 'replace',
644
- 'clear',
645
- 'typeOnly'
646
- ]).default('replace').optional().describe('Input mode: "replace" (default) - clear the field and input the value; "typeOnly" - type the value directly without clearing the field first; "clear" - clear the field without inputting new text.')),
647
- locate: (0, core_namespaceObject.getMidsceneLocationSchema)().describe('The input field to be filled').optional()
648
- }),
649
- sample: {
650
- value: 'test@example.com',
651
- locate: {
652
- prompt: 'the email input field'
653
- }
624
+ const mobileActionContext = {
625
+ input: this.inputPrimitives,
626
+ size: ()=>this.size(),
627
+ sleep: async (timeMs)=>{
628
+ await (0, utils_namespaceObject.sleep)(timeMs);
629
+ },
630
+ getDefaultAutoDismissKeyboard: ()=>this.options?.autoDismissKeyboard,
631
+ systemActions: {
632
+ backButton: {
633
+ name: 'AndroidBackButton',
634
+ description: 'Trigger the system "back" operation on Android devices'
654
635
  },
655
- call: async (param)=>{
656
- const element = param.locate;
657
- if ('typeOnly' !== param.mode) await this.clearInput(element);
658
- if ('clear' === param.mode) return;
659
- if (!param || !param.value) return;
660
- const autoDismissKeyboard = param.autoDismissKeyboard ?? this.options?.autoDismissKeyboard;
661
- await this.keyboardType(param.value, {
662
- autoDismissKeyboard
663
- });
664
- }
665
- }),
666
- (0, device_namespaceObject.defineActionScroll)(async (param)=>{
667
- const element = param.locate;
668
- const startingPoint = element ? {
669
- left: element.center[0],
670
- top: element.center[1]
671
- } : void 0;
672
- const scrollToEventName = param?.scrollType;
673
- if ('scrollToTop' === scrollToEventName) await this.scrollUntilTop(startingPoint);
674
- else if ('scrollToBottom' === scrollToEventName) await this.scrollUntilBottom(startingPoint);
675
- else if ('scrollToRight' === scrollToEventName) await this.scrollUntilRight(startingPoint);
676
- else if ('scrollToLeft' === scrollToEventName) await this.scrollUntilLeft(startingPoint);
677
- else if ('singleAction' !== scrollToEventName && scrollToEventName) throw new Error(`Unknown scroll event type: ${scrollToEventName}, param: ${JSON.stringify(param)}`);
678
- else {
679
- if (param?.direction !== 'down' && param && param.direction) if ('up' === param.direction) await this.scrollUp(param.distance || void 0, startingPoint);
680
- else if ('left' === param.direction) await this.scrollLeft(param.distance || void 0, startingPoint);
681
- else if ('right' === param.direction) await this.scrollRight(param.distance || void 0, startingPoint);
682
- else throw new Error(`Unknown scroll direction: ${param.direction}`);
683
- else await this.scrollDown(param?.distance || void 0, startingPoint);
684
- await (0, utils_namespaceObject.sleep)(500);
685
- }
686
- }),
687
- (0, device_namespaceObject.defineActionDragAndDrop)(async (param)=>{
688
- const from = param.from;
689
- const to = param.to;
690
- external_node_assert_default()(from, 'missing "from" param for drag and drop');
691
- external_node_assert_default()(to, 'missing "to" param for drag and drop');
692
- await this.mouseDrag({
693
- x: from.center[0],
694
- y: from.center[1]
695
- }, {
696
- x: to.center[0],
697
- y: to.center[1]
698
- });
699
- }),
700
- (0, device_namespaceObject.defineActionSwipe)(async (param)=>{
701
- const { startPoint, endPoint, duration, repeatCount } = (0, device_namespaceObject.normalizeMobileSwipeParam)(param, await this.size());
702
- for(let i = 0; i < repeatCount; i++)await this.mouseDrag(startPoint, endPoint, duration);
703
- }),
704
- (0, device_namespaceObject.defineActionKeyboardPress)(async (param)=>{
705
- await this.keyboardPress(param.keyName);
706
- }),
707
- (0, device_namespaceObject.defineActionCursorMove)(async (param)=>{
708
- const arrowKey = 'left' === param.direction ? 'ArrowLeft' : 'ArrowRight';
709
- const times = param.times ?? 1;
710
- for(let i = 0; i < times; i++){
711
- await this.keyboardPress(arrowKey);
712
- await (0, utils_namespaceObject.sleep)(100);
636
+ homeButton: {
637
+ name: 'AndroidHomeButton',
638
+ description: 'Trigger the system "home" operation on Android devices'
639
+ },
640
+ recentAppsButton: {
641
+ name: 'AndroidRecentAppsButton',
642
+ description: 'Trigger the system "recent apps" operation on Android devices'
713
643
  }
714
- }),
715
- (0, device_namespaceObject.defineActionLongPress)(async (param)=>{
716
- const element = param.locate;
717
- if (!element) throw new Error('LongPress requires an element to be located');
718
- const [x, y] = element.center;
719
- await this.longPress(x, y, param?.duration);
720
- }),
644
+ }
645
+ };
646
+ const defaultActions = [
647
+ ...(0, device_namespaceObject.createDefaultMobileActions)(mobileActionContext),
721
648
  (0, device_namespaceObject.defineAction)({
722
649
  name: 'PullGesture',
723
650
  description: 'Trigger pull down to refresh or pull up actions',
@@ -747,19 +674,6 @@ var __webpack_exports__ = {};
747
674
  else if ('up' === param.direction) await this.pullUp(startPoint, param.distance, param.duration);
748
675
  else throw new Error(`Unknown pull direction: ${param.direction}`);
749
676
  }
750
- }),
751
- (0, device_namespaceObject.defineActionPinch)(async (param)=>{
752
- const { centerX, centerY, startDistance, endDistance, duration } = (0, device_namespaceObject.normalizePinchParam)(param, await this.size());
753
- const { x: adjCenterX, y: adjCenterY } = await this.adjustCoordinates(centerX, centerY);
754
- const ratio = 0 !== adjCenterX && 0 !== centerX ? adjCenterX / centerX : 1;
755
- const adjStartDist = Math.round(startDistance * ratio);
756
- const adjEndDist = Math.round(endDistance * ratio);
757
- await this.ensureYadb();
758
- const adb = await this.getAdb();
759
- await adb.shell(`app_process${this.getDisplayArg()} -Djava.class.path=/data/local/tmp/yadb /data/local/tmp com.ysbing.yadb.Main -pinch ${adjCenterX} ${adjCenterY} ${adjStartDist} ${adjEndDist} ${duration}`);
760
- }),
761
- (0, device_namespaceObject.defineActionClearInput)(async (param)=>{
762
- await this.clearInput(param.locate);
763
677
  })
764
678
  ];
765
679
  const platformSpecificActions = Object.values(createPlatformActions(this));
@@ -770,6 +684,27 @@ var __webpack_exports__ = {};
770
684
  ...customActions
771
685
  ];
772
686
  }
687
+ async performActionScroll(param) {
688
+ const element = param.locate;
689
+ const startingPoint = element ? {
690
+ left: element.center[0],
691
+ top: element.center[1]
692
+ } : void 0;
693
+ const scrollToEventName = param?.scrollType;
694
+ if ('scrollToTop' === scrollToEventName) await this.scrollUntilTop(startingPoint);
695
+ else if ('scrollToBottom' === scrollToEventName) await this.scrollUntilBottom(startingPoint);
696
+ else if ('scrollToRight' === scrollToEventName) await this.scrollUntilRight(startingPoint);
697
+ else if ('scrollToLeft' === scrollToEventName) await this.scrollUntilLeft(startingPoint);
698
+ else if ('singleAction' !== scrollToEventName && scrollToEventName) throw new Error(`Unknown scroll event type: ${scrollToEventName}, param: ${JSON.stringify(param)}`);
699
+ else {
700
+ if (param?.direction !== 'down' && param && param.direction) if ('up' === param.direction) await this.scrollUp(param.distance || void 0, startingPoint);
701
+ else if ('left' === param.direction) await this.scrollLeft(param.distance || void 0, startingPoint);
702
+ else if ('right' === param.direction) await this.scrollRight(param.distance || void 0, startingPoint);
703
+ else throw new Error(`Unknown scroll direction: ${param.direction}`);
704
+ else await this.scrollDown(param?.distance || void 0, startingPoint);
705
+ await (0, utils_namespaceObject.sleep)(500);
706
+ }
707
+ }
773
708
  describe() {
774
709
  return this.description || `DeviceId: ${this.deviceId}`;
775
710
  }
@@ -1257,14 +1192,20 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
1257
1192
  return result;
1258
1193
  }
1259
1194
  async clearInput(element) {
1260
- if (element) await this.mouseClick(element.center[0], element.center[1]);
1195
+ if (element) await this.tapPoint({
1196
+ x: element.center[0],
1197
+ y: element.center[1]
1198
+ });
1261
1199
  await this.ensureYadb();
1262
1200
  const adb = await this.getAdb();
1263
1201
  const IME_STRATEGY = (this.options?.imeStrategy || env_namespaceObject.globalConfigManager.getEnvConfigValue(env_namespaceObject.MIDSCENE_ANDROID_IME_STRATEGY)) ?? IME_STRATEGY_YADB_FOR_NON_ASCII;
1264
1202
  if (IME_STRATEGY === IME_STRATEGY_YADB_FOR_NON_ASCII) await adb.clearTextField(100);
1265
1203
  else await adb.shell(`app_process${this.getDisplayArg()} -Djava.class.path=/data/local/tmp/yadb /data/local/tmp com.ysbing.yadb.Main -keyboardClear`);
1266
1204
  if (await adb.isSoftKeyboardPresent()) return;
1267
- if (element) await this.mouseClick(element.center[0], element.center[1]);
1205
+ if (element) await this.tapPoint({
1206
+ x: element.center[0],
1207
+ y: element.center[1]
1208
+ });
1268
1209
  }
1269
1210
  async forceScreenshot(path) {
1270
1211
  await this.ensureYadb();
@@ -1285,7 +1226,7 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
1285
1226
  x: start.x,
1286
1227
  y: Math.round(height)
1287
1228
  };
1288
- await (0, shared_utils_namespaceObject.repeat)(defaultScrollUntilTimes, ()=>this.mouseDrag(start, end, defaultFastScrollDuration));
1229
+ await (0, shared_utils_namespaceObject.repeat)(defaultScrollUntilTimes, ()=>this.dragPoint(start, end, defaultFastScrollDuration));
1289
1230
  await (0, utils_namespaceObject.sleep)(1000);
1290
1231
  return;
1291
1232
  }
@@ -1302,7 +1243,7 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
1302
1243
  x: start.x,
1303
1244
  y: 0
1304
1245
  };
1305
- await (0, shared_utils_namespaceObject.repeat)(defaultScrollUntilTimes, ()=>this.mouseDrag(start, end, defaultFastScrollDuration));
1246
+ await (0, shared_utils_namespaceObject.repeat)(defaultScrollUntilTimes, ()=>this.dragPoint(start, end, defaultFastScrollDuration));
1306
1247
  await (0, utils_namespaceObject.sleep)(1000);
1307
1248
  return;
1308
1249
  }
@@ -1320,7 +1261,7 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
1320
1261
  x: Math.round(width),
1321
1262
  y: start.y
1322
1263
  };
1323
- await (0, shared_utils_namespaceObject.repeat)(defaultScrollUntilTimes, ()=>this.mouseDrag(start, end, defaultFastScrollDuration));
1264
+ await (0, shared_utils_namespaceObject.repeat)(defaultScrollUntilTimes, ()=>this.dragPoint(start, end, defaultFastScrollDuration));
1324
1265
  await (0, utils_namespaceObject.sleep)(1000);
1325
1266
  return;
1326
1267
  }
@@ -1337,7 +1278,7 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
1337
1278
  x: 0,
1338
1279
  y: start.y
1339
1280
  };
1340
- await (0, shared_utils_namespaceObject.repeat)(defaultScrollUntilTimes, ()=>this.mouseDrag(start, end, defaultFastScrollDuration));
1281
+ await (0, shared_utils_namespaceObject.repeat)(defaultScrollUntilTimes, ()=>this.dragPoint(start, end, defaultFastScrollDuration));
1341
1282
  await (0, utils_namespaceObject.sleep)(1000);
1342
1283
  return;
1343
1284
  }
@@ -1355,7 +1296,7 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
1355
1296
  };
1356
1297
  const end = this.calculateScrollEndPoint(start, 0, scrollDistance, 0, height);
1357
1298
  if (hasExplicitDistance) this.warnScrollDistanceClamped('up', scrollDistance, Math.abs(end.y - start.y));
1358
- await this.mouseDrag(start, end);
1299
+ await this.dragPoint(start, end);
1359
1300
  return;
1360
1301
  }
1361
1302
  await this.scroll(0, -scrollDistance, void 0, hasExplicitDistance, 'up');
@@ -1371,7 +1312,7 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
1371
1312
  };
1372
1313
  const end = this.calculateScrollEndPoint(start, 0, -scrollDistance, 0, height);
1373
1314
  if (hasExplicitDistance) this.warnScrollDistanceClamped('down', scrollDistance, Math.abs(end.y - start.y));
1374
- await this.mouseDrag(start, end);
1315
+ await this.dragPoint(start, end);
1375
1316
  return;
1376
1317
  }
1377
1318
  await this.scroll(0, scrollDistance, void 0, hasExplicitDistance, 'down');
@@ -1387,7 +1328,7 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
1387
1328
  };
1388
1329
  const end = this.calculateScrollEndPoint(start, scrollDistance, 0, width, 0);
1389
1330
  if (hasExplicitDistance) this.warnScrollDistanceClamped('left', scrollDistance, Math.abs(end.x - start.x));
1390
- await this.mouseDrag(start, end);
1331
+ await this.dragPoint(start, end);
1391
1332
  return;
1392
1333
  }
1393
1334
  await this.scroll(-scrollDistance, 0, void 0, hasExplicitDistance, 'left');
@@ -1403,7 +1344,7 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
1403
1344
  };
1404
1345
  const end = this.calculateScrollEndPoint(start, -scrollDistance, 0, width, 0);
1405
1346
  if (hasExplicitDistance) this.warnScrollDistanceClamped('right', scrollDistance, Math.abs(end.x - start.x));
1406
- await this.mouseDrag(start, end);
1347
+ await this.dragPoint(start, end);
1407
1348
  return;
1408
1349
  }
1409
1350
  await this.scroll(scrollDistance, 0, void 0, hasExplicitDistance, 'right');
@@ -1424,7 +1365,7 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
1424
1365
  const hasBothQuotes = text.includes('"') && text.includes("'");
1425
1366
  return hasNonAscii || hasFormatSpecifiers || hasShellSpecialChars || hasBothQuotes;
1426
1367
  }
1427
- async keyboardType(text, options) {
1368
+ async typeText(text, options) {
1428
1369
  if (!text) return;
1429
1370
  const adb = await this.getAdb();
1430
1371
  const IME_STRATEGY = (this.options?.imeStrategy || env_namespaceObject.globalConfigManager.getEnvConfigValue(env_namespaceObject.MIDSCENE_ANDROID_IME_STRATEGY)) ?? IME_STRATEGY_YADB_FOR_NON_ASCII;
@@ -1461,7 +1402,7 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
1461
1402
  const lowerKey = key.toLowerCase();
1462
1403
  return keyMap[lowerKey] || key;
1463
1404
  }
1464
- async keyboardPress(key) {
1405
+ async pressKey(key) {
1465
1406
  const keyCodeMap = {
1466
1407
  Enter: 66,
1467
1408
  Backspace: 67,
@@ -1483,14 +1424,14 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
1483
1424
  if (asciiCode >= 65 && asciiCode <= 90) await adb.keyevent(asciiCode - 36);
1484
1425
  }
1485
1426
  }
1486
- async mouseClick(x, y) {
1427
+ async tapPoint(point) {
1487
1428
  const adb = await this.getAdb();
1488
- const { x: adjustedX, y: adjustedY } = await this.adjustCoordinates(x, y);
1429
+ const { x: adjustedX, y: adjustedY } = await this.adjustCoordinates(point.x, point.y);
1489
1430
  await adb.shell(`input${this.getDisplayArg()} swipe ${adjustedX} ${adjustedY} ${adjustedX} ${adjustedY} 150`);
1490
1431
  }
1491
- async mouseDoubleClick(x, y) {
1432
+ async doubleTapPoint(point) {
1492
1433
  const adb = await this.getAdb();
1493
- const { x: adjustedX, y: adjustedY } = await this.adjustCoordinates(x, y);
1434
+ const { x: adjustedX, y: adjustedY } = await this.adjustCoordinates(point.x, point.y);
1494
1435
  const tapCommand = `input${this.getDisplayArg()} tap ${adjustedX} ${adjustedY}`;
1495
1436
  await adb.shell(tapCommand);
1496
1437
  await (0, utils_namespaceObject.sleep)(50);
@@ -1499,12 +1440,14 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
1499
1440
  async mouseMove() {
1500
1441
  return Promise.resolve();
1501
1442
  }
1502
- async mouseDrag(from, to, duration) {
1443
+ async dragPoint(from, to, duration) {
1444
+ await this.swipePoint(from, to, duration ?? defaultNormalScrollDuration);
1445
+ }
1446
+ async swipePoint(from, to, duration) {
1503
1447
  const adb = await this.getAdb();
1504
1448
  const { x: fromX, y: fromY } = await this.adjustCoordinates(from.x, from.y);
1505
1449
  const { x: toX, y: toY } = await this.adjustCoordinates(to.x, to.y);
1506
- const swipeDuration = duration ?? defaultNormalScrollDuration;
1507
- await adb.shell(`input${this.getDisplayArg()} swipe ${fromX} ${fromY} ${toX} ${toY} ${swipeDuration}`);
1450
+ await adb.shell(`input${this.getDisplayArg()} swipe ${fromX} ${fromY} ${toX} ${toY} ${duration}`);
1508
1451
  }
1509
1452
  async scroll(deltaX, deltaY, duration, warnOnClamp = false, direction) {
1510
1453
  if (0 === deltaX && 0 === deltaY) throw new Error('Scroll distance cannot be zero in both directions');
@@ -1527,11 +1470,14 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
1527
1470
  }
1528
1471
  const endX = Math.round(startX - deltaX);
1529
1472
  const endY = Math.round(startY - deltaY);
1530
- const { x: adjustedStartX, y: adjustedStartY } = await this.adjustCoordinates(startX, startY);
1531
- const { x: adjustedEndX, y: adjustedEndY } = await this.adjustCoordinates(endX, endY);
1532
- const adb = await this.getAdb();
1533
1473
  const swipeDuration = duration ?? defaultNormalScrollDuration;
1534
- await adb.shell(`input${this.getDisplayArg()} swipe ${adjustedStartX} ${adjustedStartY} ${adjustedEndX} ${adjustedEndY} ${swipeDuration}`);
1474
+ await this.swipePoint({
1475
+ x: startX,
1476
+ y: startY
1477
+ }, {
1478
+ x: endX,
1479
+ y: endY
1480
+ }, swipeDuration);
1535
1481
  }
1536
1482
  async destroy() {
1537
1483
  if (this.destroyed) return;
@@ -1579,9 +1525,9 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
1579
1525
  const adb = await this.getAdb();
1580
1526
  await adb.shell(`input${this.getDisplayArg()} keyevent 187`);
1581
1527
  }
1582
- async longPress(x, y, duration = 2000) {
1528
+ async longPressPoint(point, duration = 2000) {
1583
1529
  const adb = await this.getAdb();
1584
- const { x: adjustedX, y: adjustedY } = await this.adjustCoordinates(x, y);
1530
+ const { x: adjustedX, y: adjustedY } = await this.adjustCoordinates(point.x, point.y);
1585
1531
  await adb.shell(`input${this.getDisplayArg()} swipe ${adjustedX} ${adjustedY} ${adjustedX} ${adjustedY} ${duration}`);
1586
1532
  }
1587
1533
  async pullDown(startPoint, distance, duration = 800) {
@@ -1602,10 +1548,7 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
1602
1548
  await (0, utils_namespaceObject.sleep)(200);
1603
1549
  }
1604
1550
  async pullDrag(from, to, duration) {
1605
- const adb = await this.getAdb();
1606
- const { x: fromX, y: fromY } = await this.adjustCoordinates(from.x, from.y);
1607
- const { x: toX, y: toY } = await this.adjustCoordinates(to.x, to.y);
1608
- await adb.shell(`input${this.getDisplayArg()} swipe ${fromX} ${fromY} ${toX} ${toY} ${duration}`);
1551
+ await this.swipePoint(from, to, duration);
1609
1552
  }
1610
1553
  async pullUp(startPoint, distance, duration = 600) {
1611
1554
  const { width, height } = await this.size();
@@ -1706,6 +1649,56 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
1706
1649
  device_define_property(this, "interfaceType", 'android');
1707
1650
  device_define_property(this, "uri", void 0);
1708
1651
  device_define_property(this, "options", void 0);
1652
+ device_define_property(this, "inputPrimitives", {
1653
+ pointer: {
1654
+ tap: (point)=>this.tapPoint(point),
1655
+ doubleClick: (point)=>this.doubleTapPoint(point),
1656
+ longPress: (point, opts)=>this.longPressPoint(point, opts?.duration),
1657
+ dragAndDrop: (from, to)=>this.dragPoint(from, to)
1658
+ },
1659
+ keyboard: {
1660
+ keyboardPress: (keyName)=>this.pressKey(keyName),
1661
+ typeText: async (value, opts)=>{
1662
+ const target = opts?.target;
1663
+ if (target && opts?.replace !== false) await this.clearInput(target);
1664
+ else if (target) await this.tapPoint({
1665
+ x: target.center[0],
1666
+ y: target.center[1]
1667
+ });
1668
+ if (opts?.focusOnly) return;
1669
+ await this.typeText(value, opts);
1670
+ },
1671
+ clearInput: (target)=>this.clearInput(target),
1672
+ cursorMove: async (direction, times = 1)=>{
1673
+ const arrowKey = 'left' === direction ? 'ArrowLeft' : 'ArrowRight';
1674
+ for(let i = 0; i < times; i++)await this.pressKey(arrowKey);
1675
+ }
1676
+ },
1677
+ touch: {
1678
+ swipe: async (start, end, opts)=>{
1679
+ const duration = opts?.duration ?? 300;
1680
+ const repeatCount = opts?.repeat ?? 1;
1681
+ for(let i = 0; i < repeatCount; i++)await this.dragPoint(start, end, duration);
1682
+ },
1683
+ pinch: async (center, opts)=>{
1684
+ const { x: adjCenterX, y: adjCenterY } = await this.adjustCoordinates(Math.round(center.x), Math.round(center.y));
1685
+ const ratio = 0 !== adjCenterX && 0 !== center.x ? adjCenterX / center.x : 1;
1686
+ const adjStartDist = Math.round(opts.startDistance * ratio);
1687
+ const adjEndDist = Math.round(opts.endDistance * ratio);
1688
+ await this.ensureYadb();
1689
+ const adb = await this.getAdb();
1690
+ await adb.shell(`app_process${this.getDisplayArg()} -Djava.class.path=/data/local/tmp/yadb /data/local/tmp com.ysbing.yadb.Main -pinch ${adjCenterX} ${adjCenterY} ${adjStartDist} ${adjEndDist} ${opts.duration}`);
1691
+ }
1692
+ },
1693
+ scroll: {
1694
+ scroll: (param)=>this.performActionScroll(param)
1695
+ },
1696
+ system: {
1697
+ backButton: ()=>this.back(),
1698
+ homeButton: ()=>this.home(),
1699
+ recentAppsButton: ()=>this.recentApps()
1700
+ }
1701
+ });
1709
1702
  external_node_assert_default()(deviceId, 'deviceId is required for AndroidDevice');
1710
1703
  this.deviceId = deviceId;
1711
1704
  this.options = options;
@@ -1756,37 +1749,10 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
1756
1749
  description: 'Terminate (force-stop) an Android app by package name',
1757
1750
  interfaceAlias: 'terminate',
1758
1751
  paramSchema: terminateParamSchema,
1759
- delayBeforeRunner: 0,
1760
- delayAfterRunner: 0,
1761
1752
  call: async (param)=>{
1762
1753
  if (!param.uri || '' === param.uri.trim()) throw new Error('Terminate requires a non-empty uri parameter');
1763
1754
  await device.terminate(param.uri);
1764
1755
  }
1765
- }),
1766
- AndroidBackButton: (0, device_namespaceObject.defineAction)({
1767
- name: 'AndroidBackButton',
1768
- description: 'Trigger the system "back" operation on Android devices',
1769
- delayBeforeRunner: 0,
1770
- delayAfterRunner: 0,
1771
- call: async ()=>{
1772
- await device.back();
1773
- }
1774
- }),
1775
- AndroidHomeButton: (0, device_namespaceObject.defineAction)({
1776
- name: 'AndroidHomeButton',
1777
- description: 'Trigger the system "home" operation on Android devices',
1778
- delayBeforeRunner: 0,
1779
- delayAfterRunner: 0,
1780
- call: async ()=>{
1781
- await device.home();
1782
- }
1783
- }),
1784
- AndroidRecentAppsButton: (0, device_namespaceObject.defineAction)({
1785
- name: 'AndroidRecentAppsButton',
1786
- description: 'Trigger the system "recent apps" operation on Android devices',
1787
- call: async ()=>{
1788
- await device.recentApps();
1789
- }
1790
1756
  })
1791
1757
  });
1792
1758
  const agent_namespaceObject = require("@midscene/core/agent");