assistsx-js 0.0.1 → 0.0.12

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/README-DEV.md ADDED
@@ -0,0 +1,350 @@
1
+ ### 基本用法
2
+
3
+ ```typescript
4
+ import { AssistsX, Node } from 'assistsx-js';
5
+
6
+ // 获取所有节点
7
+ const nodes: Node[] = AssistsX.getAllNodes();
8
+
9
+ // 通过ID查找节点
10
+ const nodeList: Node[] = AssistsX.findById('target_id');
11
+
12
+ // 点击第一个节点
13
+ if (nodeList.length > 0) {
14
+ AssistsX.click(nodeList[0]);
15
+ }
16
+
17
+ // 执行手势点击
18
+ AssistsX.gestureClick(100, 200, 50); // 在(100,200)位置点击,持续50ms
19
+ ```
20
+
21
+ ### 节点对象的常用操作
22
+
23
+ ```typescript
24
+ const node: Node = nodeList[0];
25
+
26
+ // 设置节点文本
27
+ node.setNodeText('new text');
28
+
29
+ // 节点点击
30
+ node.click();
31
+
32
+ // 节点长按
33
+ node.longClick();
34
+
35
+ // 节点滚动
36
+ node.scrollForward();
37
+ node.scrollBackward();
38
+
39
+ // 获取节点在屏幕中的位置
40
+ const bounds = node.getBoundsInScreen();
41
+ console.log(bounds);
42
+
43
+ // 节点截图
44
+ const imagePath = await node.takeScreenshot();
45
+ ```
46
+
47
+ ### 复杂查找与遍历
48
+
49
+ ```typescript
50
+ // 通过文本查找节点
51
+ const textNodes = AssistsX.findByText('确定');
52
+
53
+ // 通过标签查找节点
54
+ const tagNodes = AssistsX.findByTags('android.widget.Button', { filterText: '提交' });
55
+
56
+ // 获取节点的所有子节点
57
+ const children = node.getChildren();
58
+ ```
59
+
60
+ ## 主要类型说明
61
+
62
+ ### AssistsX
63
+
64
+ - 提供静态方法用于节点查找、手势操作、系统操作等。
65
+ - 常用方法:
66
+ - `getAllNodes`:获取所有节点
67
+ - `findById`、`findByText`、`findByTags`:多种查找方式
68
+ - `click`、`longClick`、`gestureClick`:节点点击与手势
69
+ - `takeScreenshotNodes`:节点截图
70
+ - `launchApp`、`back`、`home`、`notifications`、`recentApps`:系统操作
71
+
72
+ ### Node
73
+
74
+ - 表示界面上的一个可交互元素,包含属性和操作方法。
75
+ - 主要属性:
76
+ - `nodeId`、`text`、`des`、`viewId`、`className`
77
+ - `isScrollable`、`isClickable`、`isEnabled`
78
+ - 主要方法:
79
+ - `setNodeText(text: string)`:设置文本
80
+ - `click()`、`longClick()`:点击/长按
81
+ - `scrollForward()`、`scrollBackward()`:滚动
82
+ - `getBoundsInScreen()`:获取屏幕位置
83
+ - `takeScreenshot()`:节点截图
84
+ - `findById`、`findByText`、`findByTags`:在当前节点范围内查找
85
+
86
+ ## 典型场景
87
+
88
+ ### 1. 自动化测试
89
+
90
+ ```typescript
91
+ // 启动应用
92
+ AssistsX.launchApp('com.example.app');
93
+
94
+ // 等待并点击登录按钮
95
+ const loginBtn = AssistsX.findByText('登录');
96
+ if (loginBtn.length > 0) {
97
+ loginBtn[0].click();
98
+ }
99
+
100
+ // 检查是否包含某文本
101
+ const hasText = AssistsX.containsText('登录成功');
102
+ ```
103
+
104
+ ### 2. 界面元素操作
105
+
106
+ ```typescript
107
+ // 查找输入框并输入文本
108
+ const input = AssistsX.findById('input_field');
109
+ if (input.length > 0) {
110
+ input[0].setNodeText('测试文本');
111
+ }
112
+
113
+ // 查找并点击提交按钮
114
+ const submit = AssistsX.findByText('提交');
115
+ if (submit.length > 0) {
116
+ submit[0].click();
117
+ }
118
+ ```
119
+
120
+ ### 3. 手势操作
121
+
122
+ ```typescript
123
+ // 简单点击
124
+ AssistsX.gestureClick(100, 200, 50);
125
+
126
+ // 节点手势点击(支持偏移)
127
+ const node = AssistsX.findById('target')[0];
128
+ await node.nodeGestureClick({
129
+ offsetX: 10,
130
+ offsetY: 10,
131
+ clickDuration: 50
132
+ });
133
+
134
+ // 双击操作
135
+ await node.nodeGestureClickByDouble({
136
+ clickInterval: 200
137
+ });
138
+ ```
139
+
140
+ ### 4. 滚动和导航
141
+
142
+ ```typescript
143
+ // 系统导航
144
+ AssistsX.back(); // 返回
145
+ AssistsX.home(); // 主页
146
+ AssistsX.notifications(); // 通知栏
147
+
148
+ // 滚动操作
149
+ const scrollable = AssistsX.findByTags('android.widget.ScrollView')[0];
150
+ scrollable.scrollForward();
151
+ scrollable.scrollBackward();
152
+ ```
153
+
154
+ ## 步骤器(Step)使用说明
155
+
156
+ 步骤器提供了一种结构化的方式来组织和执行自动化操作,支持步骤的生命周期管理、状态控制和界面操作。
157
+
158
+ ### 基本用法
159
+
160
+ ```typescript
161
+ import { Step } from 'assistsx-js';
162
+
163
+ // 定义步骤实现
164
+ async function loginStep(step: Step): Promise<Step | undefined> {
165
+ // 启动应用
166
+ step.launchApp('com.example.app');
167
+
168
+ // 查找用户名输入框并输入
169
+ const usernameInput = step.findById('username_input');
170
+ if (usernameInput.length > 0) {
171
+ usernameInput[0].setNodeText('user123');
172
+ }
173
+
174
+ // 查找密码输入框并输入
175
+ const passwordInput = step.findById('password_input');
176
+ if (passwordInput.length > 0) {
177
+ passwordInput[0].setNodeText('password123');
178
+ }
179
+
180
+ // 点击登录按钮
181
+ const loginButton = step.findByText('登录');
182
+ if (loginButton.length > 0) {
183
+ loginButton[0].click();
184
+ }
185
+
186
+ // 返回 undefined 表示步骤结束
187
+ return undefined;
188
+ }
189
+
190
+ // 运行步骤
191
+ await Step.run(loginStep, {
192
+ tag: 'login', // 步骤标签
193
+ data: { user: 'test' }, // 步骤数据
194
+ delayMs: 1000 // 步骤延迟
195
+ });
196
+ ```
197
+
198
+ ### 步骤链式调用
199
+
200
+ ```typescript
201
+ async function step1(step: Step): Promise<Step | undefined> {
202
+ // 执行某些操作
203
+ // ...
204
+
205
+ // 返回下一个步骤
206
+ return step.next(step2, { tag: 'step2' });
207
+ }
208
+
209
+ async function step2(step: Step): Promise<Step | undefined> {
210
+ // 执行某些操作
211
+ // ...
212
+
213
+ // 重复当前步骤
214
+ if (needRepeat) {
215
+ return step.repeat();
216
+ }
217
+
218
+ // 返回下一个步骤
219
+ return step.next(step3, { tag: 'step3' });
220
+ }
221
+
222
+ async function step3(step: Step): Promise<Step | undefined> {
223
+ // 执行最后的操作
224
+ // ...
225
+
226
+ // 步骤结束
227
+ return undefined;
228
+ }
229
+
230
+ // 运行步骤链
231
+ await Step.run(step1, { tag: 'step1' });
232
+ ```
233
+
234
+ ### 异步操作处理
235
+
236
+ ```typescript
237
+ async function asyncStep(step: Step): Promise<Step | undefined> {
238
+ // 等待异步操作
239
+ await step.delay(1000);
240
+
241
+ // 执行异步方法
242
+ const result = await step.await(async () => {
243
+ // 异步操作
244
+ return 'result';
245
+ });
246
+
247
+ // 节点截图
248
+ const node = step.findById('target')[0];
249
+ const imagePath = await step.takeScreenshotByNode(node);
250
+
251
+ return undefined;
252
+ }
253
+ ```
254
+
255
+ ## Step API 文档
256
+
257
+ ### 静态方法
258
+
259
+ #### `Step.run(impl, options)`
260
+ 运行步骤实现。
261
+ - `impl`: `(step: Step) => Promise<Step | undefined>` - 步骤实现函数
262
+ - `options`:
263
+ - `tag?: string` - 步骤标签
264
+ - `data?: any` - 步骤数据
265
+ - `delayMs?: number` - 步骤延迟时间(毫秒),默认 1000
266
+
267
+ #### `Step.stop()`
268
+ 停止当前步骤执行。
269
+
270
+ ### 实例属性
271
+
272
+ - `stepId: string` - 步骤ID
273
+ - `repeatCount: number` - 步骤重复执行次数
274
+ - `tag?: string` - 步骤标签
275
+ - `data?: any` - 步骤数据
276
+ - `delayMs: number` - 步骤延迟时间(毫秒)
277
+
278
+ ### 实例方法
279
+
280
+ #### 步骤控制
281
+ - `next(impl, options)` - 创建下一个步骤
282
+ - `repeat(options)` - 重复当前步骤
283
+ - `delay(ms)` - 延迟执行
284
+ - `await<T>(method)` - 等待异步方法执行完成
285
+
286
+ #### 节点操作
287
+ - `getAllNodes(options)` - 获取所有符合条件的节点
288
+ - `findById(id, options)` - 通过ID查找节点
289
+ - `findByText(text, options)` - 通过文本查找节点
290
+ - `findByTags(className, options)` - 通过标签查找节点
291
+ - `findByTextAllMatch(text)` - 查找所有匹配文本的节点
292
+ - `findFirstParentByTags(className)` - 查找第一个匹配标签的父节点
293
+
294
+ #### 界面操作
295
+ - `takeScreenshotByNode(node, delay)` - 对单个节点进行截图
296
+ - `takeScreenshotNodes(nodes, delay)` - 对多个节点进行截图
297
+ - `gestureClick(x, y, duration)` - 执行点击手势
298
+ - `back()` - 返回操作
299
+ - `home()` - 回到主页
300
+ - `notifications()` - 打开通知栏
301
+ - `recentApps()` - 显示最近应用
302
+
303
+ #### 应用控制
304
+ - `launchApp(packageName)` - 启动应用
305
+ - `getPackageName()` - 获取当前应用包名
306
+
307
+ #### 其他操作
308
+ - `containsText(text)` - 检查是否包含指定文本
309
+ - `getAllText()` - 获取所有文本
310
+ - `getScreenSize()` - 获取屏幕尺寸
311
+ - `getAppScreenSize()` - 获取应用窗口尺寸
312
+
313
+ ## 最佳实践
314
+
315
+ 1. 步骤组织
316
+ - 将复杂的自动化流程拆分为多个步骤
317
+ - 每个步骤专注于完成特定的任务
318
+ - 使用有意义的标签和数据来标识步骤
319
+
320
+ 2. 错误处理
321
+ ```typescript
322
+ async function robustStep(step: Step): Promise<Step | undefined> {
323
+ try {
324
+ const node = step.findById('target')[0];
325
+ if (!node) {
326
+ throw new Error('Target node not found');
327
+ }
328
+ // ... 其他操作
329
+ } catch (error) {
330
+ console.error(`Step failed: ${error.message}`);
331
+ // 可以选择重试或执行其他步骤
332
+ return step.repeat({ delayMs: 2000 });
333
+ }
334
+ }
335
+ ```
336
+
337
+ 3. 步骤复用
338
+ ```typescript
339
+ // 创建可复用的步骤
340
+ function createLoginStep(username: string, password: string) {
341
+ return async function(step: Step): Promise<Step | undefined> {
342
+ // ... 登录逻辑
343
+ return undefined;
344
+ }
345
+ }
346
+
347
+ // 在不同地方复用
348
+ await Step.run(createLoginStep('user1', 'pass1'));
349
+ await Step.run(createLoginStep('user2', 'pass2'));
350
+ ```
package/README.md CHANGED
@@ -1,388 +1,132 @@
1
- # AssistsX
1
+ # AssistsX JS
2
2
 
3
- Android WebView 辅助功能库,提供了一系列用于与 Android WebView 交互的 TypeScript 类型和方法,支持节点查找、手势操作、界面自动化等能力。
3
+ 一个支持通过Web端实现Android平台自动化脚本的JS库,支持元素节点查找、获取节点文本、节点截图、执行手势动作、提供步骤器实现复杂自动化业务等一系列自动化脚本开发能力支持
4
4
 
5
- ## 安装
5
+ # AssistsX JS运行平台
6
+ 开发的自动化脚本需要运行在Android端[AssistsX](https://www.pgyer.com/SqGaCx8C)中,所以开发前需要先在手机安装[AssistsX](https://www.pgyer.com/SqGaCx8C)
6
7
 
7
- ```bash
8
- npm install assistsx
9
- ```
8
+ **扫码下载**
10
9
 
11
- ## 快速开始
10
+ <img width="112" alt="image" src="https://github.com/user-attachments/assets/c28ecc41-01f8-4e52-9ddc-80dc5c6d0ed5" />
12
11
 
13
- ### 基本用法
12
+ **下载链接:[https://www.pgyer.com/SqGaCx8C](https://www.pgyer.com/SqGaCx8C)**
14
13
 
15
- ```typescript
16
- import { AssistsX, Node } from 'assistsx';
14
+ > 下载安装后会默认安装一个示例插件,可长按删除
17
15
 
18
- // 获取所有节点
19
- const nodes: Node[] = AssistsX.getAllNodes();
16
+ # 示例源码安装运行
20
17
 
21
- // 通过ID查找节点
22
- const nodeList: Node[] = AssistsX.findById('target_id');
18
+ 源码:[https://github.com/ven-coder/assistsx-js-simple](https://github.com/ven-coder/assistsx-js-simple)
23
19
 
24
- // 点击第一个节点
25
- if (nodeList.length > 0) {
26
- AssistsX.click(nodeList[0]);
27
- }
20
+ ## 本地安装运行
28
21
 
29
- // 执行手势点击
30
- AssistsX.gestureClick(100, 200, 50); // 在(100,200)位置点击,持续50ms
31
- ```
22
+ ### 1. 安装[AssistsX](https://www.pgyer.com/SqGaCx8C)
32
23
 
33
- ### 节点对象的常用操作
24
+ 安装前请先在手机安装[AssistsX](https://www.pgyer.com/SqGaCx8C)
34
25
 
35
- ```typescript
36
- const node: Node = nodeList[0];
26
+ ### 2. 插件包传至手机
27
+ 下载本示例源码后(*前提`npm`环境配置好*)
28
+ 1. 终端依次运行命令:`npm install`,`npm run build`
29
+ 2. 编译完成后将`dist`文件夹压缩为`.zip`文件,然后将`.zip`文件传至手机。
30
+ 3. 手机打开[AssistsX](https://www.pgyer.com/SqGaCx8C),点击+号->本地添加->选择传至手机的`zip`压缩包
37
31
 
38
- // 设置节点文本
39
- node.setNodeText('new text');
40
32
 
41
- // 节点点击
42
- node.click();
33
+ <img src="https://github.com/user-attachments/assets/7dc27910-be61-473b-8900-f09c16ca5f46" width="250">
43
34
 
44
- // 节点长按
45
- node.longClick();
35
+ ## 局域网加载运行
36
+ > 确保手机与电脑处于同一个局域网
37
+ ### 1. 安装[AssistsX](https://www.pgyer.com/SqGaCx8C)
38
+ 加载运行前请先在手机安装[AssistsX](https://www.pgyer.com/SqGaCx8C)
46
39
 
47
- // 节点滚动
48
- node.scrollForward();
49
- node.scrollBackward();
40
+ ### 2. 启动项目
41
+ 下载本示例源码后,终端依次运行命令:`npm install`,`npm run dev`
50
42
 
51
- // 获取节点在屏幕中的位置
52
- const bounds = node.getBoundsInScreen();
53
- console.log(bounds);
54
-
55
- // 节点截图
56
- const imagePath = await node.takeScreenshot();
57
- ```
43
+ ### 3. 加载插件
44
+ 手机打开[AssistsX](https://www.pgyer.com/SqGaCx8C),点击+号->扫描局域网->点击扫描到插件+号
58
45
 
59
- ### 复杂查找与遍历
46
+ <img src="https://github.com/user-attachments/assets/d0f24763-266e-4e3c-bd64-a63be9e6c68c" width="250"/>
60
47
 
61
- ```typescript
62
- // 通过文本查找节点
63
- const textNodes = AssistsX.findByText('确定');
64
-
65
- // 通过标签查找节点
66
- const tagNodes = AssistsX.findByTags('android.widget.Button', { filterText: '提交' });
67
-
68
- // 获取节点的所有子节点
69
- const children = node.getChildren();
48
+ # 快速开始
49
+ ## 1. 创建项目
50
+ - 创建`vite`模版项目:`npm create vite@latest assistsx-helloword -- --template vue`
51
+ - 安装`assistsx-js`依赖:`npm install assistsx-js@latest`
52
+ ## 2. 创建插件配置
53
+ 在项目目录`public`下创建文件`assistsx_plugin_config.json`文件,将以下`json`复制粘贴到文件中
70
54
  ```
71
-
72
- ## 主要类型说明
73
-
74
- ### AssistsX
75
-
76
- - 提供静态方法用于节点查找、手势操作、系统操作等。
77
- - 常用方法:
78
- - `getAllNodes`:获取所有节点
79
- - `findById`、`findByText`、`findByTags`:多种查找方式
80
- - `click`、`longClick`、`gestureClick`:节点点击与手势
81
- - `takeScreenshotNodes`:节点截图
82
- - `launchApp`、`back`、`home`、`notifications`、`recentApps`:系统操作
83
-
84
- ### Node
85
-
86
- - 表示界面上的一个可交互元素,包含属性和操作方法。
87
- - 主要属性:
88
- - `nodeId`、`text`、`des`、`viewId`、`className`
89
- - `isScrollable`、`isClickable`、`isEnabled`
90
- - 主要方法:
91
- - `setNodeText(text: string)`:设置文本
92
- - `click()`、`longClick()`:点击/长按
93
- - `scrollForward()`、`scrollBackward()`:滚动
94
- - `getBoundsInScreen()`:获取屏幕位置
95
- - `takeScreenshot()`:节点截图
96
- - `findById`、`findByText`、`findByTags`:在当前节点范围内查找
97
-
98
- ## 典型场景
99
-
100
- ### 1. 自动化测试
101
-
102
- ```typescript
103
- // 启动应用
104
- AssistsX.launchApp('com.example.app');
105
-
106
- // 等待并点击登录按钮
107
- const loginBtn = AssistsX.findByText('登录');
108
- if (loginBtn.length > 0) {
109
- loginBtn[0].click();
55
+ {
56
+ "name": "AssistsX示例",
57
+ "version": "1.0.0",
58
+ "description": "AssistsX示例",
59
+ "isShowOverlay": true,
60
+ "needScreenCapture": true,
61
+ "packageName": "com.assistsx.example",
62
+ "main": "index.html",
63
+ "icon": "vite.svg",
64
+ "overlayTitle": "AssistsX示例"
110
65
  }
111
-
112
- // 检查是否包含某文本
113
- const hasText = AssistsX.containsText('登录成功');
114
66
  ```
115
-
116
- ### 2. 界面元素操作
117
-
118
- ```typescript
119
- // 查找输入框并输入文本
120
- const input = AssistsX.findById('input_field');
121
- if (input.length > 0) {
122
- input[0].setNodeText('测试文本');
67
+ ## 3. 编写脚本插件
68
+ 写一个最简单的,点击微信搜索进入搜索页面
69
+ ```agsl
70
+ const handleClick = () => {
71
+ AssistsX.findById("com.tencent.mm:id/jha")[0].click()
123
72
  }
73
+ ```
124
74
 
125
- // 查找并点击提交按钮
126
- const submit = AssistsX.findByText('提交');
127
- if (submit.length > 0) {
128
- submit[0].click();
129
- }
75
+ 增加一个测试按钮调用这个方法
76
+ ```agsl
77
+ <button type="button" @click="handleClick">测试按钮</button>
130
78
  ```
131
79
 
132
- ### 3. 手势操作
80
+ ## 4. 加载插件
81
+ 1. 通过[AssistsX](https://www.pgyer.com/SqGaCx8C)局域网加载插件
82
+ > 加载插件前需要配置项目允许局域网访问,在文件`vite.config.js`添加以下配置
83
+ ```
84
+ export default defineConfig({
85
+ plugins: [vue()],
86
+ server: {
87
+ host: '0.0.0.0', // 允许局域网访问
88
+ port: 5173
89
+ },
90
+ })
91
+ ```
92
+ 运行项目`npm run dev`以便`AssistsX`直接加载
133
93
 
134
- ```typescript
135
- // 简单点击
136
- AssistsX.gestureClick(100, 200, 50);
94
+ 1. 打开`AssistsX`,扫描局域网插件添加
137
95
 
138
- // 节点手势点击(支持偏移)
139
- const node = AssistsX.findById('target')[0];
140
- await node.nodeGestureClick({
141
- offsetX: 10,
142
- offsetY: 10,
143
- clickDuration: 50
144
- });
96
+ <img src="https://github.com/user-attachments/assets/d0f24763-266e-4e3c-bd64-a63be9e6c68c" width="250"/>
145
97
 
146
- // 双击操作
147
- await node.nodeGestureClickByDouble({
148
- clickInterval: 200
149
- });
150
- ```
98
+ 3. 测试插件:点击开始,打开微信消息列表,点击测试按钮
151
99
 
152
- ### 4. 滚动和导航
100
+ <img src="https://github.com/user-attachments/assets/e6e59149-ed78-42de-81a7-c3476b5472e6" width="250"/>
153
101
 
154
- ```typescript
155
- // 系统导航
156
- AssistsX.back(); // 返回
157
- AssistsX.home(); // 主页
158
- AssistsX.notifications(); // 通知栏
159
102
 
160
- // 滚动操作
161
- const scrollable = AssistsX.findByTags('android.widget.ScrollView')[0];
162
- scrollable.scrollForward();
163
- scrollable.scrollBackward();
164
- ```
103
+ <br/>
104
+ <br/>
165
105
 
166
- ## 注意事项
167
-
168
- 1. 使用前提
169
- - 确保 Android WebView 中已注入 `assistsx` 对象
170
- - 确保有足够的权限(如辅助功能权限)
171
-
172
- 2. 性能建议
173
- - 避免频繁查找节点,建议复用查找结果
174
- - 截图等耗时操作请合理使用
175
-
176
- 3. 异步操作
177
- - 截图、手势等操作为异步方法,需使用 `await`
178
- - 建议使用 try-catch 处理异常
179
-
180
- 4. 节点状态
181
- - 操作前建议检查节点的 `isEnabled`、`isClickable` 等状态
182
- - 使用 `isVisible` 确认节点是否可见
183
-
184
- ## API 文档
185
-
186
- 详细的 API 文档请参考源码中的 TypeScript 类型定义和注释说明。
187
-
188
- ## 问题反馈
189
-
190
- 如有问题或建议,欢迎提交 Issue 或 Pull Request。
191
-
192
- ## 步骤器(Step)使用说明
193
-
194
- 步骤器提供了一种结构化的方式来组织和执行自动化操作,支持步骤的生命周期管理、状态控制和界面操作。
195
-
196
- ### 基本用法
197
-
198
- ```typescript
199
- import { Step } from 'assistsx';
200
-
201
- // 定义步骤实现
202
- async function loginStep(step: Step): Promise<Step | undefined> {
203
- // 启动应用
204
- step.launchApp('com.example.app');
205
-
206
- // 查找用户名输入框并输入
207
- const usernameInput = step.findById('username_input');
208
- if (usernameInput.length > 0) {
209
- usernameInput[0].setNodeText('user123');
210
- }
211
-
212
- // 查找密码输入框并输入
213
- const passwordInput = step.findById('password_input');
214
- if (passwordInput.length > 0) {
215
- passwordInput[0].setNodeText('password123');
216
- }
217
-
218
- // 点击登录按钮
219
- const loginButton = step.findByText('登录');
220
- if (loginButton.length > 0) {
221
- loginButton[0].click();
222
- }
223
-
224
- // 返回 undefined 表示步骤结束
225
- return undefined;
226
- }
106
+ **[API开发文档](https://github.com/ven-coder/assistsx-js/blob/main/README-DEV.md)**
227
107
 
228
- // 运行步骤
229
- await Step.run(loginStep, {
230
- tag: 'login', // 步骤标签
231
- data: { user: 'test' }, // 步骤数据
232
- delayMs: 1000 // 步骤延迟
233
- });
234
- ```
108
+ ## 🙋有问题欢迎反馈交流
235
109
 
236
- ### 步骤链式调用
110
+ | QQ交流群| 个人微信 |
111
+ |:---------:|:-----------:|
112
+ | <img src="https://github.com/user-attachments/assets/732c38a5-7473-44ca-be76-d1fabb27aa5d" width=200/> | <img src="https://github.com/user-attachments/assets/b805f5a0-223b-415d-a34b-7659aa0bdf0a" width=200/>
237
113
 
238
- ```typescript
239
- async function step1(step: Step): Promise<Step | undefined> {
240
- // 执行某些操作
241
- // ...
242
-
243
- // 返回下一个步骤
244
- return step.next(step2, { tag: 'step2' });
245
- }
114
+ # 💝 支持开源
246
115
 
247
- async function step2(step: Step): Promise<Step | undefined> {
248
- // 执行某些操作
249
- // ...
250
-
251
- // 重复当前步骤
252
- if (needRepeat) {
253
- return step.repeat();
254
- }
255
-
256
- // 返回下一个步骤
257
- return step.next(step3, { tag: 'step3' });
258
- }
116
+ 开源不易,您的支持是我坚持的动力!
259
117
 
260
- async function step3(step: Step): Promise<Step | undefined> {
261
- // 执行最后的操作
262
- // ...
263
-
264
- // 步骤结束
265
- return undefined;
266
- }
118
+ 如果AssistsX JS对您的项目有帮助,可以通过以下方式支持我喔:
267
119
 
268
- // 运行步骤链
269
- await Step.run(step1, { tag: 'step1' });
270
- ```
120
+ ### ⭐ Star支持
121
+ - 给项目点个Star,让更多开发者发现这个框架
122
+ - 分享给身边的朋友和同事
271
123
 
272
- ### 异步操作处理
273
-
274
- ```typescript
275
- async function asyncStep(step: Step): Promise<Step | undefined> {
276
- // 等待异步操作
277
- await step.delay(1000);
278
-
279
- // 执行异步方法
280
- const result = await step.await(async () => {
281
- // 异步操作
282
- return 'result';
283
- });
284
-
285
- // 节点截图
286
- const node = step.findById('target')[0];
287
- const imagePath = await step.takeScreenshotByNode(node);
288
-
289
- return undefined;
290
- }
291
- ```
124
+ ### 💰 赞助支持
125
+ - [爱发电支持](https://afdian.com/a/vencoder) - 您的每一份支持都是我们前进的动力
126
+ - 一杯Coffee的微信赞赏
127
+
128
+ <img width="200" alt="image" src="https://github.com/user-attachments/assets/3862a40c-631c-4ab0-b1e7-00ec3e3e00ad" />
129
+
130
+ **定制开发可联系个人微信: x39598**
292
131
 
293
- ## Step API 文档
294
-
295
- ### 静态方法
296
-
297
- #### `Step.run(impl, options)`
298
- 运行步骤实现。
299
- - `impl`: `(step: Step) => Promise<Step | undefined>` - 步骤实现函数
300
- - `options`:
301
- - `tag?: string` - 步骤标签
302
- - `data?: any` - 步骤数据
303
- - `delayMs?: number` - 步骤延迟时间(毫秒),默认 1000
304
-
305
- #### `Step.stop()`
306
- 停止当前步骤执行。
307
-
308
- ### 实例属性
309
-
310
- - `stepId: string` - 步骤ID
311
- - `repeatCount: number` - 步骤重复执行次数
312
- - `tag?: string` - 步骤标签
313
- - `data?: any` - 步骤数据
314
- - `delayMs: number` - 步骤延迟时间(毫秒)
315
-
316
- ### 实例方法
317
-
318
- #### 步骤控制
319
- - `next(impl, options)` - 创建下一个步骤
320
- - `repeat(options)` - 重复当前步骤
321
- - `delay(ms)` - 延迟执行
322
- - `await<T>(method)` - 等待异步方法执行完成
323
-
324
- #### 节点操作
325
- - `getAllNodes(options)` - 获取所有符合条件的节点
326
- - `findById(id, options)` - 通过ID查找节点
327
- - `findByText(text, options)` - 通过文本查找节点
328
- - `findByTags(className, options)` - 通过标签查找节点
329
- - `findByTextAllMatch(text)` - 查找所有匹配文本的节点
330
- - `findFirstParentByTags(className)` - 查找第一个匹配标签的父节点
331
-
332
- #### 界面操作
333
- - `takeScreenshotByNode(node, delay)` - 对单个节点进行截图
334
- - `takeScreenshotNodes(nodes, delay)` - 对多个节点进行截图
335
- - `gestureClick(x, y, duration)` - 执行点击手势
336
- - `back()` - 返回操作
337
- - `home()` - 回到主页
338
- - `notifications()` - 打开通知栏
339
- - `recentApps()` - 显示最近应用
340
-
341
- #### 应用控制
342
- - `launchApp(packageName)` - 启动应用
343
- - `getPackageName()` - 获取当前应用包名
344
-
345
- #### 其他操作
346
- - `containsText(text)` - 检查是否包含指定文本
347
- - `getAllText()` - 获取所有文本
348
- - `getScreenSize()` - 获取屏幕尺寸
349
- - `getAppScreenSize()` - 获取应用窗口尺寸
350
-
351
- ## 最佳实践
352
-
353
- 1. 步骤组织
354
- - 将复杂的自动化流程拆分为多个步骤
355
- - 每个步骤专注于完成特定的任务
356
- - 使用有意义的标签和数据来标识步骤
357
-
358
- 2. 错误处理
359
- ```typescript
360
- async function robustStep(step: Step): Promise<Step | undefined> {
361
- try {
362
- const node = step.findById('target')[0];
363
- if (!node) {
364
- throw new Error('Target node not found');
365
- }
366
- // ... 其他操作
367
- } catch (error) {
368
- console.error(`Step failed: ${error.message}`);
369
- // 可以选择重试或执行其他步骤
370
- return step.repeat({ delayMs: 2000 });
371
- }
372
- }
373
- ```
374
-
375
- 3. 步骤复用
376
- ```typescript
377
- // 创建可复用的步骤
378
- function createLoginStep(username: string, password: string) {
379
- return async function(step: Step): Promise<Step | undefined> {
380
- // ... 登录逻辑
381
- return undefined;
382
- }
383
- }
384
-
385
- // 在不同地方复用
386
- await Step.run(createLoginStep('user1', 'pass1'));
387
- await Step.run(createLoginStep('user2', 'pass2'));
388
- ```
132
+ **感谢所有的支持者,得到你们的支持我将会更加完善开源库的能力!** 🚀
package/dist/AssistsX.js CHANGED
@@ -204,7 +204,7 @@ export class AssistsX {
204
204
  * @returns 节点数组
205
205
  */
206
206
  static findByTextAllMatch(text) {
207
- const response = this.call(CallMethod.findByTextAllMatch, { args: text });
207
+ const response = this.call(CallMethod.findByTextAllMatch, { args: { text } });
208
208
  return Node.fromJSONArray(response.getDataOrDefault("[]"));
209
209
  }
210
210
  /**
@@ -213,7 +213,7 @@ export class AssistsX {
213
213
  * @returns 是否包含
214
214
  */
215
215
  static containsText(text) {
216
- const response = this.call(CallMethod.containsText, { args: text });
216
+ const response = this.call(CallMethod.containsText, { args: { text } });
217
217
  return response.getDataOrDefault(false);
218
218
  }
219
219
  /**
@@ -230,7 +230,7 @@ export class AssistsX {
230
230
  * @returns 父节点
231
231
  */
232
232
  static findFirstParentByTags(className) {
233
- const response = this.call(CallMethod.findFirstParentByTags, { args: className });
233
+ const response = this.call(CallMethod.findFirstParentByTags, { args: { className } });
234
234
  return Node.create(response.getDataOrDefault("{}"));
235
235
  }
236
236
  /**
package/dist/Node.d.ts CHANGED
@@ -93,7 +93,7 @@ export declare class Node {
93
93
  * @param filterDes 描述过滤
94
94
  * @returns 节点数组
95
95
  */
96
- findByTags(className: string, { filterText, filterViewId, filterDes }: {
96
+ findByTags(className: string, { filterText, filterViewId, filterDes }?: {
97
97
  filterText?: string;
98
98
  filterViewId?: string;
99
99
  filterDes?: string;
package/dist/Node.js CHANGED
@@ -54,7 +54,7 @@ export class Node {
54
54
  * @param filterDes 描述过滤
55
55
  * @returns 节点数组
56
56
  */
57
- findByTags(className, { filterText, filterViewId, filterDes }) {
57
+ findByTags(className, { filterText, filterViewId, filterDes } = {}) {
58
58
  Step.assert(this.stepId);
59
59
  const result = AssistsX.findByTags(className, { filterText, filterViewId, filterDes, node: this });
60
60
  Step.assignIdsToNodes(result, this.stepId);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "assistsx-js",
3
- "version": "0.0.1",
3
+ "version": "0.0.12",
4
4
  "description": "assistsx-js自动化开发SDK",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
package/src/AssistsX.ts CHANGED
@@ -230,7 +230,7 @@ export class AssistsX {
230
230
  * @returns 节点数组
231
231
  */
232
232
  public static findByTextAllMatch(text: string): Node[] {
233
- const response = this.call(CallMethod.findByTextAllMatch, { args: text });
233
+ const response = this.call(CallMethod.findByTextAllMatch, { args: { text } });
234
234
  return Node.fromJSONArray(response.getDataOrDefault("[]"));
235
235
  }
236
236
 
@@ -240,7 +240,7 @@ export class AssistsX {
240
240
  * @returns 是否包含
241
241
  */
242
242
  public static containsText(text: string): boolean {
243
- const response = this.call(CallMethod.containsText, { args: text });
243
+ const response = this.call(CallMethod.containsText, { args: { text } });
244
244
  return response.getDataOrDefault(false);
245
245
  }
246
246
 
@@ -259,7 +259,7 @@ export class AssistsX {
259
259
  * @returns 父节点
260
260
  */
261
261
  public static findFirstParentByTags(className: string): Node {
262
- const response = this.call(CallMethod.findFirstParentByTags, { args: className });
262
+ const response = this.call(CallMethod.findFirstParentByTags, { args: { className } });
263
263
  return Node.create(response.getDataOrDefault("{}"));
264
264
  }
265
265
 
package/src/Node.ts CHANGED
@@ -116,7 +116,7 @@ export class Node {
116
116
  * @param filterDes 描述过滤
117
117
  * @returns 节点数组
118
118
  */
119
- public findByTags(className: string, { filterText, filterViewId, filterDes }: { filterText?: string, filterViewId?: string, filterDes?: string, }): Node[] {
119
+ public findByTags(className: string, { filterText, filterViewId, filterDes }: { filterText?: string, filterViewId?: string, filterDes?: string, } = {}): Node[] {
120
120
  Step.assert(this.stepId);
121
121
  const result = AssistsX.findByTags(className, { filterText, filterViewId, filterDes, node: this });
122
122
  Step.assignIdsToNodes(result, this.stepId);