Skip to content

Commit 953553e

Browse files
committed
fix(android): simplify scroll methods by removing startPoint parameter and enhancing scrolling logic (#1039)
* fix(android): simplify scroll methods by removing startPoint parameter and enhancing scrolling logic * fix(android): enhance scrolling methods to support startPoint parameter and improve swipe duration handling * docs(site): update acknowledgments to include Rslib as a build tool
1 parent 50b8148 commit 953553e

File tree

4 files changed

+70
-37
lines changed

4 files changed

+70
-37
lines changed

apps/site/docs/en/index.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ There are so many UI automation tools out there, and each one seems to be all-po
108108

109109
We would like to thank the following projects:
110110

111-
- [Rsbuild](https://github.com/web-infra-dev/rsbuild) for the build tool.
111+
- [Rsbuild](https://github.com/web-infra-dev/rsbuild) and [Rslib](https://github.com/web-infra-dev/rslib) for the build tool.
112112
- [UI-TARS](https://github.com/bytedance/ui-tars) for the open-source agent model UI-TARS.
113113
- [Qwen2.5-VL](https://github.com/QwenLM/Qwen2.5-VL) for the open-source VL model Qwen2.5-VL.
114114
- [scrcpy](https://github.com/Genymobile/scrcpy) and [yume-chan](https://github.com/yume-chan) allow us to control Android devices with browser.

apps/site/docs/zh/index.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ for (const record of recordList) {
105105

106106
我们要感谢以下项目:
107107

108-
- [Rsbuild](https://github.com/web-infra-dev/rsbuild) 提供构建工具。
108+
- [Rsbuild](https://github.com/web-infra-dev/rsbuild) [Rslib](https://github.com/web-infra-dev/rslib) 提供构建工具。
109109
- [UI-TARS](https://github.com/bytedance/ui-tars) 提供开源智能体模型 UI-TARS。
110110
- [Qwen2.5-VL](https://github.com/QwenLM/Qwen2.5-VL) 提供开源 VL 模型 Qwen2.5-VL。
111111
- [scrcpy](https://github.com/Genymobile/scrcpy)[yume-chan](https://github.com/yume-chan) 让我们能够用浏览器控制 Android 设备。

packages/android/src/page/index.ts

Lines changed: 61 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -522,11 +522,14 @@ ${Object.keys(size)
522522
get mouse() {
523523
return {
524524
click: (x: number, y: number) => this.mouseClick(x, y),
525-
wheel: (deltaX: number, deltaY: number) =>
526-
this.mouseWheel(deltaX, deltaY),
525+
wheel: (deltaX: number, deltaY: number, duration?: number) =>
526+
this.mouseWheel(deltaX, deltaY, duration),
527527
move: (x: number, y: number) => this.mouseMove(x, y),
528-
drag: (from: { x: number; y: number }, to: { x: number; y: number }) =>
529-
this.mouseDrag(from, to),
528+
drag: (
529+
from: { x: number; y: number },
530+
to: { x: number; y: number },
531+
duration?: number,
532+
) => this.mouseDrag(from, to, duration),
530533
};
531534
}
532535

@@ -582,59 +585,74 @@ ${Object.keys(size)
582585

583586
async scrollUntilTop(startPoint?: Point): Promise<void> {
584587
if (startPoint) {
588+
const { height } = await this.size();
585589
const start = { x: startPoint.left, y: startPoint.top };
586-
const end = { x: start.x, y: 0 };
590+
const end = { x: start.x, y: height };
587591

588-
await this.mouseDrag(start, end);
592+
await repeat(defaultScrollUntilTimes, () =>
593+
this.mouseDrag(start, end, defaultFastScrollDuration),
594+
);
595+
await sleep(1000);
589596
return;
590597
}
591598

592599
await repeat(defaultScrollUntilTimes, () =>
593-
this.mouseWheel(0, 9999999, defaultFastScrollDuration),
600+
this.mouseWheel(0, -9999999, defaultFastScrollDuration),
594601
);
595602
await sleep(1000);
596603
}
597604

598605
async scrollUntilBottom(startPoint?: Point): Promise<void> {
599606
if (startPoint) {
600-
const { height } = await this.size();
601607
const start = { x: startPoint.left, y: startPoint.top };
602-
const end = { x: start.x, y: height };
603-
await this.mouseDrag(start, end);
608+
const end = { x: start.x, y: 0 };
609+
610+
await repeat(defaultScrollUntilTimes, () =>
611+
this.mouseDrag(start, end, defaultFastScrollDuration),
612+
);
613+
await sleep(1000);
604614
return;
605615
}
606616

607617
await repeat(defaultScrollUntilTimes, () =>
608-
this.mouseWheel(0, -9999999, defaultFastScrollDuration),
618+
this.mouseWheel(0, 9999999, defaultFastScrollDuration),
609619
);
610620
await sleep(1000);
611621
}
612622

613623
async scrollUntilLeft(startPoint?: Point): Promise<void> {
614624
if (startPoint) {
625+
const { width } = await this.size();
615626
const start = { x: startPoint.left, y: startPoint.top };
616-
const end = { x: 0, y: start.y };
617-
await this.mouseDrag(start, end);
627+
const end = { x: width, y: start.y };
628+
629+
await repeat(defaultScrollUntilTimes, () =>
630+
this.mouseDrag(start, end, defaultFastScrollDuration),
631+
);
632+
await sleep(1000);
618633
return;
619634
}
620635

621636
await repeat(defaultScrollUntilTimes, () =>
622-
this.mouseWheel(9999999, 0, defaultFastScrollDuration),
637+
this.mouseWheel(-9999999, 0, defaultFastScrollDuration),
623638
);
624639
await sleep(1000);
625640
}
626641

627642
async scrollUntilRight(startPoint?: Point): Promise<void> {
628643
if (startPoint) {
629-
const { width } = await this.size();
630644
const start = { x: startPoint.left, y: startPoint.top };
631-
const end = { x: width, y: start.y };
632-
await this.mouseDrag(start, end);
645+
const end = { x: 0, y: start.y };
646+
647+
await repeat(defaultScrollUntilTimes, () =>
648+
this.mouseDrag(start, end, defaultFastScrollDuration),
649+
);
650+
await sleep(1000);
633651
return;
634652
}
635653

636654
await repeat(defaultScrollUntilTimes, () =>
637-
this.mouseWheel(-9999999, 0, defaultFastScrollDuration),
655+
this.mouseWheel(9999999, 0, defaultFastScrollDuration),
638656
);
639657
await sleep(1000);
640658
}
@@ -645,13 +663,13 @@ ${Object.keys(size)
645663

646664
if (startPoint) {
647665
const start = { x: startPoint.left, y: startPoint.top };
648-
const endY = Math.max(0, start.y - scrollDistance);
666+
const endY = Math.min(height, start.y + scrollDistance);
649667
const end = { x: start.x, y: endY };
650668
await this.mouseDrag(start, end);
651669
return;
652670
}
653671

654-
await this.mouseWheel(0, scrollDistance);
672+
await this.mouseWheel(0, -scrollDistance);
655673
}
656674

657675
async scrollDown(distance?: number, startPoint?: Point): Promise<void> {
@@ -660,13 +678,13 @@ ${Object.keys(size)
660678

661679
if (startPoint) {
662680
const start = { x: startPoint.left, y: startPoint.top };
663-
const endY = Math.min(height, start.y + scrollDistance);
681+
const endY = Math.max(0, start.y - scrollDistance);
664682
const end = { x: start.x, y: endY };
665683
await this.mouseDrag(start, end);
666684
return;
667685
}
668686

669-
await this.mouseWheel(0, -scrollDistance);
687+
await this.mouseWheel(0, scrollDistance);
670688
}
671689

672690
async scrollLeft(distance?: number, startPoint?: Point): Promise<void> {
@@ -675,13 +693,13 @@ ${Object.keys(size)
675693

676694
if (startPoint) {
677695
const start = { x: startPoint.left, y: startPoint.top };
678-
const endX = Math.max(0, start.x - scrollDistance);
696+
const endX = Math.min(width, start.x + scrollDistance);
679697
const end = { x: endX, y: start.y };
680698
await this.mouseDrag(start, end);
681699
return;
682700
}
683701

684-
await this.mouseWheel(scrollDistance, 0);
702+
await this.mouseWheel(-scrollDistance, 0);
685703
}
686704

687705
async scrollRight(distance?: number, startPoint?: Point): Promise<void> {
@@ -690,13 +708,13 @@ ${Object.keys(size)
690708

691709
if (startPoint) {
692710
const start = { x: startPoint.left, y: startPoint.top };
693-
const endX = Math.min(width, start.x + scrollDistance);
711+
const endX = Math.max(0, start.x - scrollDistance);
694712
const end = { x: endX, y: start.y };
695713
await this.mouseDrag(start, end);
696714
return;
697715
}
698716

699-
await this.mouseWheel(-scrollDistance, 0);
717+
await this.mouseWheel(scrollDistance, 0);
700718
}
701719

702720
private async ensureYadb() {
@@ -807,20 +825,26 @@ ${Object.keys(size)
807825
private async mouseDrag(
808826
from: { x: number; y: number },
809827
to: { x: number; y: number },
828+
duration?: number,
810829
): Promise<void> {
811830
const adb = await this.getAdb();
812831

813832
// Use adjusted coordinates
814833
const { x: fromX, y: fromY } = this.adjustCoordinates(from.x, from.y);
815834
const { x: toX, y: toY } = this.adjustCoordinates(to.x, to.y);
816835

817-
await adb.shell(`input swipe ${fromX} ${fromY} ${toX} ${toY} 300`);
836+
// Ensure duration has a default value
837+
const swipeDuration = duration ?? 300;
838+
839+
await adb.shell(
840+
`input swipe ${fromX} ${fromY} ${toX} ${toY} ${swipeDuration}`,
841+
);
818842
}
819843

820844
private async mouseWheel(
821845
deltaX: number,
822846
deltaY: number,
823-
duration = defaultNormalScrollDuration,
847+
duration?: number,
824848
): Promise<void> {
825849
const { width, height } = await this.size();
826850

@@ -842,8 +866,11 @@ ${Object.keys(size)
842866
deltaY = Math.max(-maxNegativeDeltaY, Math.min(deltaY, maxPositiveDeltaY));
843867

844868
// Calculate the end coordinates
845-
const endX = startX + deltaX;
846-
const endY = startY + deltaY;
869+
// Note: For swipe, we need to reverse the delta direction
870+
// because positive deltaY should scroll up (show top content),
871+
// which requires swiping from bottom to top (decreasing Y)
872+
const endX = startX - deltaX;
873+
const endY = startY - deltaY;
847874

848875
// Adjust coordinates to fit device ratio
849876
const { x: adjustedStartX, y: adjustedStartY } = this.adjustCoordinates(
@@ -857,9 +884,12 @@ ${Object.keys(size)
857884

858885
const adb = await this.getAdb();
859886

887+
// Ensure duration has a default value
888+
const swipeDuration = duration ?? defaultNormalScrollDuration;
889+
860890
// Execute the swipe operation
861891
await adb.shell(
862-
`input swipe ${adjustedStartX} ${adjustedStartY} ${adjustedEndX} ${adjustedEndY} ${duration}`,
892+
`input swipe ${adjustedStartX} ${adjustedStartY} ${adjustedEndX} ${adjustedEndY} ${swipeDuration}`,
863893
);
864894
}
865895

packages/android/tests/ai/setting.test.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,16 @@ describe(
1616
});
1717

1818
await agent.launch('com.android.settings/.Settings');
19-
2019
await agent.aiAction('scroll list to bottom');
2120
await agent.aiAction('open "More settings"');
22-
await agent.aiAction('scroll list to bottom');
21+
await agent.aiAction('scroll left until left edge');
22+
await agent.aiAction('scroll right until right edge');
2323
await agent.aiAction('scroll list to top');
24-
await agent.aiAction('swipe down one screen');
25-
await agent.aiAction('swipe up one screen');
24+
await agent.aiAction('scroll list to bottom');
25+
await agent.aiAction('scroll down one screen');
26+
await agent.aiAction('scroll up one screen');
27+
await agent.aiAction('scroll right one screen');
28+
await agent.aiAction('scroll left one screen');
2629
});
2730
},
2831
360 * 1000,

0 commit comments

Comments
 (0)