mirror of
https://github.com/web-infra-dev/midscene.git
synced 2025-07-25 18:01:27 +00:00
159 lines
6.1 KiB
Plaintext
159 lines
6.1 KiB
Plaintext
# 支持 Android 自动化
|
||
|
||
我们很高兴地宣布:从 Midscene v0.15 开始,我们开始支持 Android 自动化。AI 驱动的 Android 自动化时代已经到来!
|
||
|
||
## 案例展示
|
||
|
||
### 地图导航到景点
|
||
|
||
打开地图 App,搜索目的地,然后发起导航。
|
||
|
||
<video src="https://lf3-static.bytednsdoc.com/obj/eden-cn/nupipfups/Midscene/android-maps.mp4" controls/>
|
||
|
||
### Twitter 自动点赞
|
||
|
||
打开 Twitter,自动点赞 [@midscene_ai](https://x.com/midscene_ai) 的第一个推文。
|
||
|
||
<video src="https://lf3-static.bytednsdoc.com/obj/eden-cn/nupipfups/Midscene/android-twitter.mp4" controls/>
|
||
|
||
## 适配所有的应用
|
||
|
||
对于我们的开发者来说,你只需要 adb 和一个视觉语言(visual language, VL)模型服务。所有的准备工作就做好了!
|
||
|
||
在运行期,我们利用 VL 模型的视觉定位能力来定位屏幕上的目标元素。因此,无论是原生 App ,[Lynx](https://github.com/lynx-family/lynx) 页面还是 Hybrid App 中的 webview,它都无关紧要。开发者可以编写自动化脚本,而无需担心 App 本身的技术栈。
|
||
|
||
## 引入 Midscene 的全部特性
|
||
|
||
当使用 Midscene 进行 Web 自动化时,我们的用户喜欢使用我们的 Playground 和运行报告能力。现在,我们已经将这些特性引入到 Android 自动化中!
|
||
|
||
### 使用 Playground 来试用 Android 自动化,而不需要写任何代码
|
||
|
||
<video src="https://lf3-static.bytednsdoc.com/obj/eden-cn/nupipfups/Midscene/android-playground-lark-en.mp4" poster="/blog/android-playground-lark-poster-cn.png" controls/>
|
||
|
||
### 使用报告重放整个过程
|
||
|
||
<video src="https://lf3-static.bytednsdoc.com/obj/eden-cn/nupipfups/Midscene/android-ebay.mp4" controls/>
|
||
|
||
### 使用 YAML 文件编写自动化脚本
|
||
|
||
```yaml
|
||
# search headphone on ebay, extract the items info into a json file, and assert the shopping cart icon
|
||
|
||
android:
|
||
deviceId: s4ey59
|
||
|
||
tasks:
|
||
- name: search headphones
|
||
flow:
|
||
- aiAction: open browser and navigate to ebay.com
|
||
- aiAction: type 'Headphones' in ebay search box, hit Enter
|
||
- sleep: 5000
|
||
- aiAction: scroll down the page for 800px
|
||
|
||
- name: extract headphones info
|
||
flow:
|
||
- aiQuery: >
|
||
{name: string, price: number, subTitle: string}[], return item name, price and the subTitle on the lower right corner of each item
|
||
name: headphones
|
||
|
||
- name: assert Filter button
|
||
flow:
|
||
- aiAssert: There is a Filter button on the page
|
||
```
|
||
|
||
### 使用 JavaScript SDK 来编写自动化脚本
|
||
|
||
```ts
|
||
import { AndroidAgent, AndroidDevice, getConnectedDevices } from '@midscene/android';
|
||
import "dotenv/config"; // read environment variables from .env file
|
||
|
||
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
||
Promise.resolve(
|
||
(async () => {
|
||
const devices = await getConnectedDevices();
|
||
const page = new AndroidDevice(devices[0].udid);
|
||
|
||
// 👀 init Midscene agent
|
||
const agent = new AndroidAgent(page,{
|
||
aiActionContext:
|
||
'If any location, permission, user agreement, etc. popup, click agree. If login page pops up, close it.',
|
||
});
|
||
await page.connect();
|
||
await page.launch('https://www.ebay.com');
|
||
|
||
await sleep(5000);
|
||
|
||
// 👀 type keywords, perform a search
|
||
await agent.aiAction('type "Headphones" in search box, hit Enter');
|
||
|
||
// 👀 wait for the loading
|
||
await agent.aiWaitFor("there is at least one headphone item on page");
|
||
// or you may use a plain sleep:
|
||
// await sleep(5000);
|
||
|
||
// 👀 understand the page content, find the items
|
||
const items = await agent.aiQuery(
|
||
"{itemTitle: string, price: Number}[], find item in list and corresponding price"
|
||
);
|
||
console.log("headphones in stock", items);
|
||
|
||
// 👀 assert by AI
|
||
await agent.aiAssert("There is a category filter on the left");
|
||
})()
|
||
);
|
||
|
||
```
|
||
|
||
### 使用两种风格的 API 来执行交互
|
||
|
||
自动规划(Auto-planning)风格:
|
||
|
||
```javascript
|
||
await agent.ai('input "Headphones" in search box, hit Enter');
|
||
```
|
||
|
||
即时操作(Instant Actions)风格:
|
||
|
||
```javascript
|
||
await agent.aiInput('Headphones', 'search box');
|
||
await agent.aiKeyboardPress('Enter');
|
||
```
|
||
|
||
## 快速开始
|
||
|
||
你可以使用 Playground 工具来零代码快速体验 Android 自动化的过程,详情参阅 [使用 Android Playground 快速体验](./quick-experience-with-android)。
|
||
|
||
在体验完成后,你可以通过 Javascript 代码与 Android 设备进行集成,请参阅 [与 Android(adb) 集成](./integrate-with-android)。
|
||
|
||
如果你更偏爱 Yaml 文件形式的自动化脚本,请参阅 [使用 YAML 格式的自动化脚本](./automate-with-scripts-in-yaml)。
|
||
|
||
### 示例项目
|
||
|
||
我们准备了一个示例项目,供开发者参考:
|
||
|
||
[JavaScript 示例项目](https://github.com/web-infra-dev/midscene-example/blob/main/android/javascript-sdk-demo)
|
||
|
||
如果你想要使用自动化进行测试,你可以使用 JavaScript 和 vitest。我们为你准备了一个示例项目,来看看它是如何工作的:
|
||
|
||
[Vitest demo project](https://github.com/web-infra-dev/midscene-example/blob/main/android/vitest-demo)
|
||
|
||
此外,你也可以使用 yaml 文件来编写自动化脚本:
|
||
|
||
[YAML 示例项目](https://github.com/web-infra-dev/midscene-example/blob/main/android/yaml-scripts-demo)
|
||
|
||
## 限制
|
||
|
||
1. 无法使用元素定位的缓存功能。由于没有收集视图树,我们无法缓存元素标识符并重用它。
|
||
2. 目前只支持一些已知的 VL 模型。如果你想要引入其他 VL 模型,请让我们知道。
|
||
3. 运行性能还不够好。我们还在努力改进它。
|
||
4. VL 模型在 `.aiQuery` 和 `.aiAssert` 中表现不佳。我们将在未来提供一种方法来切换模型以适应不同的任务。
|
||
5. 由于某些安全限制,你可能会在密码输入时得到一个空白截图,Midscene 此时将无法工作。
|
||
|
||
## 致谢
|
||
|
||
我们想要感谢以下项目:
|
||
|
||
- [scrcpy](https://github.com/Genymobile/scrcpy) 和 [yume-chan](https://github.com/yume-chan) 允许我们使用浏览器控制 Android 设备。
|
||
- [appium-adb](https://github.com/appium/appium-adb) 为 adb 提供了 javascript 桥接。
|
||
- [YADB](https://github.com/ysbing/YADB) 为文本输入提供了性能提升。
|