├── .gitignore
├── .travis.yml
├── HISTORY.md
├── Makefile
├── README.md
├── checkstyle.xml
├── docs
├── allclasses-frame.html
├── allclasses-noframe.html
├── constant-values.html
├── deprecated-list.html
├── help-doc.html
├── index-all.html
├── index.html
├── macaca
│ └── java
│ │ └── biz
│ │ ├── App.html
│ │ ├── BaseErrorType.html
│ │ ├── BaseMacacaClient.GesturePinchType.html
│ │ ├── BaseMacacaClient.PlatformType.html
│ │ ├── BaseMacacaClient.html
│ │ ├── BasePage.html
│ │ ├── BasePageUI.html
│ │ ├── BaseUtils.html
│ │ ├── CommonUIBean.html
│ │ ├── ResultGenerator.html
│ │ ├── package-frame.html
│ │ ├── package-summary.html
│ │ └── package-tree.html
├── overview-tree.html
├── package-list
├── script.js
└── stylesheet.css
├── pom.xml
└── src
├── main
└── java
│ └── macaca
│ └── java
│ └── biz
│ ├── AppCommonPage.java
│ ├── BaseErrorType.java
│ ├── BaseMacacaClient.java
│ ├── BasePage.java
│ ├── BaseUtils.java
│ ├── CommonUIBean.java
│ ├── ResultGenerator.java
│ └── WebCommonPage.java
└── test
└── java
└── macaca
└── java
└── biz
└── AppTest.java
/.gitignore:
--------------------------------------------------------------------------------
1 | .classpath
2 | .project
3 | .settings/
4 | target/
5 | *.sw*
6 | *.un~
7 | .idea/
8 | *.iml
9 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: java
2 | jdk:
3 | - openjdk8
4 | script:
5 | - mvn clean install
6 |
--------------------------------------------------------------------------------
/HISTORY.md:
--------------------------------------------------------------------------------
1 | # 1.1.11 / 2017-11-02
2 |
3 | ### BaseUtil.java 增加对软键盘的处理,包含软键盘是否展示以及输入
4 | // BaseUtils.java
5 | isSoftKeyboardDisplay()
6 | 通过adb命令获取输入软键盘的状态 1、mInputShown=true 则判断软键盘弹出 2、mInputShown=false 则判断软键盘隐藏 3、执行命令失败的情况下,默认返回false
7 |
8 | inputText(java.lang.String content)
9 | 通过adb命令模拟用户输入
10 |
11 | # 1.1.4 / 2017-07-14
12 |
13 | ### 增加一个个API
14 |
15 | // BaseUtils.java
16 | * uninstallApp (String deviceType,String deviceId,String app) // 删除app Support: Android ios
17 | 各API详细使用规则可参考注释文档
18 |
19 | # 1.1 / 2017-05-04
20 |
21 | ### 修改两个API
22 |
23 | // BaseMacacaClient.java
24 | * scrollToElementCustom (GetElementWay wayToFind, String value, int stepSize) // 去掉对横屏or竖屏的判断,底层wd.java已经自适应横屏or竖屏
25 | * scrollToBottomOrTop (boolean isToBottom) // 去掉对横屏or竖屏的判断,底层wd.java已经自适应横屏or竖屏
26 | * public void scrollToTop () // 调用更新后的scrollToBottomOrTop方法
27 | * scrollToBottom() // 调用更新后的scrollToBottomOrTop方法
28 | * scrollToElement (GetElementWay wayToFind, String value) // 调用更新后的scrollToElementCustom方法
29 | 各API详细使用规则可参考注释文档
30 |
31 | # 1.0.9 / 2017-04-11
32 |
33 | ### 增加两个API
34 |
35 | // BaseUtils.java
36 | * deviceInstaller (String deviceType,String deviceId,String packagePath) // 安装app Support: Android ios
37 | * launchApp(String deviceType,String deviceId,String packageName,String activityName,String bundleId ) // 启动app Support: Android ios
38 |
39 | 各API详细使用规则可参考注释文档
40 |
41 | # 1.0.5 / 2017-03-22
42 |
43 | ### 增加一个API
44 |
45 | // BaseMacacaClient.java
46 | * scrollToBottomOrTop (boolean isHorizontal,boolean isToBottom) // 横屏或竖屏滑动到最底部或最顶部
47 |
48 | ### 修改两个API
49 |
50 | // BaseMacacaClient.java
51 | * scrollToBottom () //注释掉了之前的方法体,在里面调用了scrollToBottomOrTop (boolean isHorizontal,boolean isToBottom)实现滑动到最底部
52 | * scrollToTop () //注释掉了之前的方法体,在里面调用了scrollToBottomOrTop (boolean isHorizontal,boolean isToBottom)实现滑动到最顶部
53 |
54 | 各API详细使用规则可参考注释文档
55 |
56 | # 1.0.4 / 2017-03-17
57 |
58 | ### 增加一个API
59 |
60 | // BaseMacacaClient.java
61 | * scrollToElementCustom (GetElementWay wayToFind, String value, boolean isHorizontal, int stepSize) // 滑动当前页面到指定控件(支持横屏滑动和竖屏滑动)
62 |
63 | ### 修改一个API
64 |
65 | // BaseMacacaClient.java
66 | * scrollToElement (GetElementWay wayToFind, String value) //注释掉了之前的方法体,在里面调用了scrollToElementCustom (GetElementWay wayToFind, String value, boolean isHorizontal, int stepSize)实现滑动当前页面到指定控件
67 |
68 | 各API详细使用规则可参考注释文档
69 |
70 | # 1.0.1 / 2017-02-28
71 |
72 | ### 增加部分API
73 |
74 | // BaseMacacaClient.java
75 | * scrollToBottom() // 滑动视图到底部
76 | * scrollToTop() // 滑动视图到顶部
77 | * switchFromNativeToWebView() // 切换上下文到webview(在对webview操作前执行)
78 | * switchFromeWebviewToNative() // 切换上下文到native
79 |
80 | #1.0 / 2017-01-22
81 |
82 | ### 增加App操作相关的API,如启动app,清理app,杀死app(目前只提供针对Android平台的操作)
83 |
84 | #### 在server启动的情况下,可使用如下API
85 |
86 | // BaseMacacaClient.java
87 | * startApp()
88 | * clearApp()
89 | * forceStopApp()
90 |
91 | #### 在server未启动的情况下,无法获取正在运行的app信息,如果要操作,需要手动传入,相关API如下
92 | // BaseUtils.java
93 | * startApp(String deviceId,String packageName,String activityName)
94 | * clearApp(String deviceId,String packageName)
95 | * forceStopApp(String deviceId,String packageName)
96 |
97 | 各API详细使用规则可参考注释文档
98 |
99 | # 0.0.9 / 2016-01-10
100 |
101 | ### 1. 增加部分对控件直接操作的API,可以直接通过driver操作控件
102 |
103 | * clearText(CommonUIBean bean)
104 | * getText(CommonUIBean bean)
105 | * getProperty(CommonUIBean bean,String name)
106 | * getRect(CommonUIBean bean)
107 | * isDisplayed(CommonUIBean bean)
108 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | doc:
2 | javadoc -d ./docs -version -sourcepath ./src/main/java macaca.java.biz
3 |
4 | deploy:
5 | mvn -s settings.xml deploy -Dmaven.test.skip=true
6 |
7 | install:
8 | mvn -s settings.xml clean install -Dmaven.test.skip=true
9 | .PHONY: test
10 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # macaca-java-biz
2 |
3 | ---
4 |
5 | A framework for uiautomation business development based on macacaClient(wd.java).
6 |
7 | 基于Macaca-Java版的业务层封装框架,主要为业务使用提供便利。
8 |
9 | 底层依赖参考: [wd.java](//github.com/macacajs/wd.java)
10 |
11 | 如何引用可参考 : [macaca-java-biz-sample](//github.com/macaca-sample/macaca-java-biz-sample)
12 |
13 | ## API文档
14 |
15 | - [链接](//macaca-sample.github.io/macaca-java-biz-framework/)
16 |
17 | ``` bash
18 | # 生成文档
19 | $ make doc
20 | ```
21 |
22 | ## Release notes
23 |
24 | - [HISTORY.md](./HISTORY.md)
25 |
26 | ## 其他相关文档
27 |
28 | - [更多参考](https://testerhome.com/junhe)
29 |
30 |
31 | ## Contributors
32 |
33 | |[Yinxl ](https://github.com/Yinxl) |[rogerwild ](https://github.com/rogerwild) |[xudafeng ](https://github.com/xudafeng) |[VersionFish ](https://github.com/VersionFish)
34 | | :---: | :---: | :---: | :---: |
35 |
36 |
37 | This project follows the git-contributor [spec](https://github.com/xudafeng/git-contributor), auto upated at `Sat Apr 21 2018 17:24:00 GMT+0800`.
38 |
39 |
40 |
--------------------------------------------------------------------------------
/checkstyle.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
--------------------------------------------------------------------------------
/docs/allclasses-frame.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | All Classes
7 |
8 |
9 |
10 |
11 |
12 | All Classes
13 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/docs/allclasses-noframe.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | All Classes
7 |
8 |
9 |
10 |
11 |
12 | All Classes
13 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/docs/constant-values.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Constant Field Values
7 |
8 |
9 |
10 |
11 |
12 |
23 |
24 | JavaScript is disabled on your browser.
25 |
26 |
27 |
43 |
71 |
72 |
79 |
80 |
81 |
82 |
macaca.java.*
83 |
84 |
85 |
116 |
117 |
118 |
120 | macaca.java.biz.ResultGenerator
123 |
124 | Modifier and Type
125 | Constant Field
126 | Value
127 |
128 |
129 |
130 |
131 |
132 | public static final java.lang.String
133 | CUSTOM_LOG
134 | "custom.log"
135 |
136 |
137 |
138 |
139 | public static final java.lang.String
140 | NAME
141 | "result.log"
142 |
143 |
144 |
145 |
146 | public static final java.lang.String
147 | SEPARATOR
148 | "|"
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
172 |
173 |
174 | Prev
175 | Next
176 |
177 |
181 |
184 |
185 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
--------------------------------------------------------------------------------
/docs/deprecated-list.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Deprecated List
7 |
8 |
9 |
10 |
11 |
12 |
23 |
24 | JavaScript is disabled on your browser.
25 |
26 |
27 |
43 |
71 |
72 |
79 |
111 |
112 |
128 |
129 |
130 | Prev
131 | Next
132 |
133 |
137 |
140 |
141 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
--------------------------------------------------------------------------------
/docs/help-doc.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | API Help
7 |
8 |
9 |
10 |
11 |
12 |
23 |
24 | JavaScript is disabled on your browser.
25 |
26 |
27 |
43 |
71 |
72 |
78 |
79 |
80 |
81 | Package
82 | Each package has a page that contains a list of its classes and interfaces, with a summary for each. This
83 | page can contain six categories:
84 |
85 | Interfaces (italic)
86 | Classes
87 | Enums
88 | Exceptions
89 | Errors
90 | Annotation Types
91 |
92 |
93 |
94 | Class/Interface
95 | Each class, interface, nested class and nested interface has its own separate page. Each of these pages
96 | has three sections consisting of a class/interface description, summary tables, and detailed member
97 | descriptions:
98 |
99 | Class inheritance diagram
100 | Direct Subclasses
101 | All Known Subinterfaces
102 | All Known Implementing Classes
103 | Class/interface declaration
104 | Class/interface description
105 |
106 |
107 | Nested Class Summary
108 | Field Summary
109 | Constructor Summary
110 | Method Summary
111 |
112 |
113 | Field Detail
114 | Constructor Detail
115 | Method Detail
116 |
117 | Each summary entry contains the first sentence from the detailed description for that item. The summary
118 | entries are alphabetical, while the detailed descriptions are in the order they appear in the source
119 | code. This preserves the logical groupings established by the programmer.
120 |
121 |
122 | Annotation Type
123 | Each annotation type has its own separate page with the following sections:
124 |
125 | Annotation Type declaration
126 | Annotation Type description
127 | Required Element Summary
128 | Optional Element Summary
129 | Element Detail
130 |
131 |
132 |
133 | Enum
134 | Each enum has its own separate page with the following sections:
135 |
136 | Enum declaration
137 | Enum description
138 | Enum Constant Summary
139 | Enum Constant Detail
140 |
141 |
142 |
143 | Tree (Class Hierarchy)
144 | There is a Class Hierarchy page for all packages, plus a hierarchy for
145 | each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are
146 | organized by inheritance structure starting with java.lang.Object
. The interfaces do not
147 | inherit from java.lang.Object
.
148 |
149 | When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
150 | When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy
151 | for only that package.
152 |
153 |
154 |
155 |
156 | Deprecated API
157 | The Deprecated API page lists all of the API that have been
158 | deprecated. A deprecated API is not recommended for use, generally due to improvements, and a
159 | replacement API is usually given. Deprecated APIs may be removed in future implementations.
160 |
161 |
162 | Index
163 | The Index contains an alphabetic list of all classes, interfaces,
164 | constructors, methods, and fields.
165 |
166 |
167 | Prev/Next
168 | These links take you to the next or previous class, interface, package, or related page.
169 |
170 |
171 | Frames/No Frames
172 | These links show and hide the HTML frames. All pages are available with or without frames.
173 |
174 |
175 | All Classes
176 | The All Classes link shows all classes and interfaces except
177 | non-static nested types.
178 |
179 |
180 | Serialized Form
181 | Each serializable or externalizable class has a description of its serialization fields and methods. This
182 | information is of interest to re-implementors, not to developers using the API. While there is no link
183 | in the navigation bar, you can get to this information by going to any serialized class and clicking
184 | "Serialized Form" in the "See also" section of the class description.
185 |
186 |
187 | Constant Field Values
188 | The Constant Field Values page lists the static final fields and their
189 | values.
190 |
191 |
192 |
This help file applies to API documentation generated using the standard doclet.
193 |
194 |
195 |
211 |
212 |
213 | Prev
214 | Next
215 |
216 |
220 |
223 |
224 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
--------------------------------------------------------------------------------
/docs/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Generated Documentation (Untitled)
7 |
60 |
61 |
62 |
64 |
66 |
67 |
68 | JavaScript is disabled on your browser.
69 |
70 | Frame Alert
71 | This document is designed to be viewed using the frames feature. If you see this message, you are using a
72 | non-frame-capable web client. Link to Non-frame version .
73 |
74 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/docs/macaca/java/biz/App.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | App
7 |
8 |
9 |
10 |
11 |
12 |
29 |
30 | JavaScript is disabled on your browser.
31 |
32 |
33 |
49 |
50 |
55 |
59 |
62 |
63 |
74 |
75 |
76 |
77 | Summary:
78 | Nested |
79 | Field |
80 | Constr |
81 | Method
82 |
83 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
99 |
100 |
101 | java.lang.Object
102 |
103 |
104 | macaca.java.biz.App
105 |
106 |
107 |
108 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 | Constructor Summary
128 |
130 | Constructors
131 |
132 | Constructor and Description
133 |
134 |
135 | App ()
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 | Method Summary
148 |
150 | All Methods Static Methods Concrete Methods
156 |
157 | Modifier and Type
158 | Method and Description
159 |
160 |
161 | static void
162 | main (java.lang.String[] args)
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 | Methods inherited from class java.lang.Object
172 | clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait,
173 | wait, wait
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 | Constructor Detail
189 |
190 |
191 |
192 |
193 |
194 | App
195 | public App()
196 |
197 |
198 |
199 |
200 |
201 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
239 |
240 |
245 |
249 |
252 |
253 |
264 |
265 |
266 |
267 | Summary:
268 | Nested |
269 | Field |
270 | Constr |
271 | Method
272 |
273 |
274 | Detail:
275 | Field |
276 | Constr |
277 | Method
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
--------------------------------------------------------------------------------
/docs/macaca/java/biz/BaseMacacaClient.GesturePinchType.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | BaseMacacaClient.GesturePinchType
7 |
8 |
9 |
10 |
11 |
12 |
29 |
30 | JavaScript is disabled on your browser.
31 |
32 |
33 |
49 |
50 |
56 |
61 |
64 |
65 |
76 |
77 |
92 |
93 |
94 |
95 |
96 |
97 |
101 |
102 |
103 | java.lang.Object
104 |
105 |
114 |
115 |
116 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 | Enum Constant Summary
147 |
149 | Enum Constants
150 |
151 | Enum Constant and Description
152 |
153 |
154 | PINCH_IN
156 |
157 |
158 |
159 | PINCH_OUT
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 | Method Summary
172 |
208 |
209 |
210 |
211 |
212 | Methods inherited from class java.lang.Enum
213 | clone, compareTo, equals, finalize, getDeclaringClass, hashCode, name, ordinal,
214 | toString, valueOf
215 |
216 |
217 |
218 |
219 |
220 | Methods inherited from class java.lang.Object
221 | getClass, notify, notifyAll, wait, wait, wait
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
261 |
262 |
263 |
264 |
265 |
266 | Method Detail
267 |
268 |
269 |
270 |
292 |
293 |
294 |
295 |
296 |
297 | valueOf
298 | public static BaseMacacaClient.GesturePinchType valueOf(java.lang.String name)
301 | Returns the enum constant of this type with the specified name.
302 | The string must match exactly an identifier used to declare an
303 | enum constant in this type. (Extraneous whitespace characters are
304 | not permitted.)
305 |
306 |
307 | Parameters:
308 | name
- the name of the enum constant to be returned.
309 | Returns:
310 | the enum constant with the specified name
311 | Throws:
312 | java.lang.IllegalArgumentException
- if this enum type has no
313 | constant with the specified name
314 |
315 | java.lang.NullPointerException
- if the argument is null
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
343 |
344 |
350 |
355 |
358 |
359 |
370 |
371 |
386 |
387 |
388 |
389 |
390 |
391 |
392 |
--------------------------------------------------------------------------------
/docs/macaca/java/biz/BaseMacacaClient.PlatformType.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | BaseMacacaClient.PlatformType
7 |
8 |
9 |
10 |
11 |
12 |
29 |
30 | JavaScript is disabled on your browser.
31 |
32 |
33 |
49 |
50 |
56 |
61 |
64 |
65 |
76 |
77 |
92 |
93 |
94 |
95 |
96 |
97 |
101 |
102 |
103 | java.lang.Object
104 |
105 |
114 |
115 |
116 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 | Enum Constant Summary
147 |
149 | Enum Constants
150 |
151 | Enum Constant and Description
152 |
153 |
154 | ANDROID
156 |
157 |
158 |
159 | IOS
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 | Method Summary
172 |
206 |
207 |
208 |
209 |
210 | Methods inherited from class java.lang.Enum
211 | clone, compareTo, equals, finalize, getDeclaringClass, hashCode, name, ordinal,
212 | toString, valueOf
213 |
214 |
215 |
216 |
217 |
218 | Methods inherited from class java.lang.Object
219 | getClass, notify, notifyAll, wait, wait, wait
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
259 |
260 |
261 |
262 |
263 |
264 | Method Detail
265 |
266 |
267 |
268 |
290 |
291 |
292 |
293 |
294 |
295 | valueOf
296 | public static BaseMacacaClient.PlatformType valueOf(java.lang.String name)
299 | Returns the enum constant of this type with the specified name.
300 | The string must match exactly an identifier used to declare an
301 | enum constant in this type. (Extraneous whitespace characters are
302 | not permitted.)
303 |
304 |
305 | Parameters:
306 | name
- the name of the enum constant to be returned.
307 | Returns:
308 | the enum constant with the specified name
309 | Throws:
310 | java.lang.IllegalArgumentException
- if this enum type has no
311 | constant with the specified name
312 |
313 | java.lang.NullPointerException
- if the argument is null
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
341 |
342 |
348 |
353 |
356 |
357 |
368 |
369 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
--------------------------------------------------------------------------------
/docs/macaca/java/biz/BasePage.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | BasePage
7 |
8 |
9 |
10 |
11 |
12 |
29 |
30 | JavaScript is disabled on your browser.
31 |
32 |
33 |
49 |
50 |
56 |
60 |
63 |
64 |
75 |
76 |
91 |
92 |
93 |
94 |
95 |
96 |
100 |
101 |
102 | java.lang.Object
103 |
104 |
105 | macaca.java.biz.BasePage
106 |
107 |
108 |
109 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 | Field Summary
129 |
131 | Fields
132 |
133 | Modifier and Type
134 | Field and Description
135 |
136 |
137 | BaseMacacaClient
139 |
140 | driver
142 | antClient driver
143 |
144 |
145 |
146 | java.lang.String
147 | pageDesc
149 | page desc 页面描述,日志输出时会用到,用于对当前页面一个可辨识的描述信息
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 | Constructor Summary
161 |
163 | Constructors
164 |
165 | Constructor and Description
166 |
167 |
168 | BasePage (java.lang.String pageDesc)
170 | 构造函数 使用此方法只指定了页面描述,如果对页面进行操作,还需手动指定driver对象
171 |
172 |
173 |
174 | BasePage (java.lang.String pageDesc,
176 | BaseMacacaClient driver)
178 | 构造函数
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 | Method Summary
190 |
228 |
229 |
230 |
231 |
232 | Methods inherited from class java.lang.Object
233 | clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait,
234 | wait, wait
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
273 |
274 |
311 |
312 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
380 |
381 |
387 |
391 |
394 |
395 |
406 |
407 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
--------------------------------------------------------------------------------
/docs/macaca/java/biz/BasePageUI.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | BasePageUI
7 |
8 |
9 |
10 |
11 |
12 |
23 |
24 | JavaScript is disabled on your browser.
25 |
26 |
27 |
43 |
44 |
50 |
54 |
57 |
58 |
69 |
70 |
71 |
72 | Summary:
73 | Nested |
74 | Field |
75 | Constr |
76 | Method
77 |
78 |
79 | Detail:
80 | Field |
81 | Constr |
82 | Method
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
94 |
95 |
96 | java.lang.Object
97 |
98 |
99 | macaca.java.biz.BasePageUI
100 |
101 |
102 |
103 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 | Constructor Summary
122 |
124 | Constructors
125 |
126 | Constructor and Description
127 |
128 |
129 | BasePageUI ()
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 | Method Summary
142 |
143 |
144 |
145 |
146 | Methods inherited from class java.lang.Object
147 | clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait,
148 | wait, wait
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 | Constructor Detail
164 |
165 |
166 |
167 |
168 |
169 | BasePageUI
170 | public BasePageUI()
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
197 |
198 |
204 |
208 |
211 |
212 |
223 |
224 |
225 |
226 | Summary:
227 | Nested |
228 | Field |
229 | Constr |
230 | Method
231 |
232 |
233 | Detail:
234 | Field |
235 | Constr |
236 | Method
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
--------------------------------------------------------------------------------
/docs/macaca/java/biz/package-frame.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | macaca.java.biz
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
Classes
15 |
25 |
Enums
26 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/docs/macaca/java/biz/package-summary.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | macaca.java.biz
7 |
8 |
9 |
10 |
11 |
12 |
23 |
24 | JavaScript is disabled on your browser.
25 |
26 |
27 |
43 |
44 |
45 | Prev Package
46 | Next Package
47 |
48 |
52 |
55 |
56 |
67 |
68 |
69 |
70 |
71 |
72 |
75 |
76 |
77 |
78 |
80 | Class Summary
81 |
82 | Class
83 | Description
84 |
85 |
86 |
87 | App
88 |
89 |
90 | Hello world!
91 |
92 |
93 |
94 | BaseMacacaClient
96 |
97 | 自定义的MacacaClient基类,用于在MacacaClient基础上封装自己的处理
98 |
99 |
100 |
101 | BasePage
103 |
104 | 通用Page基类,用于页面的通用处理,比如页面返回以及其他
105 |
106 |
107 |
108 | BasePageUI
110 |
111 |
112 |
113 | BaseUtils
115 |
116 |
117 |
118 | CommonUIBean
120 |
121 |
122 |
123 | ResultGenerator
125 |
126 |
127 |
128 |
129 |
130 |
131 |
156 |
157 |
158 |
159 |
160 |
176 |
177 |
178 | Prev Package
179 | Next Package
180 |
181 |
185 |
188 |
189 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
--------------------------------------------------------------------------------
/docs/macaca/java/biz/package-tree.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | macaca.java.biz Class Hierarchy
7 |
8 |
9 |
10 |
11 |
12 |
23 |
24 | JavaScript is disabled on your browser.
25 |
26 |
27 |
43 |
71 |
72 |
75 |
76 |
Class Hierarchy
77 |
78 | java.lang.Object
79 |
106 |
107 |
108 |
Enum Hierarchy
109 |
110 | java.lang.Object
111 |
112 | java.lang.Enum<E> (implements java.lang.Comparable<T>,
113 | java.io.Serializable)
114 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
149 |
150 |
151 | Prev
152 | Next
153 |
154 |
158 |
161 |
162 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
--------------------------------------------------------------------------------
/docs/overview-tree.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Class Hierarchy
7 |
8 |
9 |
10 |
11 |
12 |
23 |
24 | JavaScript is disabled on your browser.
25 |
26 |
27 |
43 |
71 |
72 |
79 |
80 |
Class Hierarchy
81 |
82 | java.lang.Object
83 |
110 |
111 |
112 |
Enum Hierarchy
113 |
114 | java.lang.Object
115 |
116 | java.lang.Enum<E> (implements java.lang.Comparable<T>,
117 | java.io.Serializable)
118 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
152 |
153 |
154 | Prev
155 | Next
156 |
157 |
161 |
164 |
165 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
--------------------------------------------------------------------------------
/docs/package-list:
--------------------------------------------------------------------------------
1 | macaca.java.biz
2 |
--------------------------------------------------------------------------------
/docs/script.js:
--------------------------------------------------------------------------------
1 | function show(type)
2 | {
3 | count = 0;
4 | for (var key in methods) {
5 | var row = document.getElementById(key);
6 | if ((methods[key] & type) != 0) {
7 | row.style.display = '';
8 | row.className = (count++ % 2) ? rowColor : altColor;
9 | }
10 | else
11 | row.style.display = 'none';
12 | }
13 | updateTabs(type);
14 | }
15 |
16 | function updateTabs(type)
17 | {
18 | for (var value in tabs) {
19 | var sNode = document.getElementById(tabs[value][0]);
20 | var spanNode = sNode.firstChild;
21 | if (value == type) {
22 | sNode.className = activeTableTab;
23 | spanNode.innerHTML = tabs[value][1];
24 | }
25 | else {
26 | sNode.className = tableTab;
27 | spanNode.innerHTML = "" + tabs[value][1] + " ";
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/docs/stylesheet.css:
--------------------------------------------------------------------------------
1 | /* Javadoc style sheet */
2 | /*
3 | Overall document style
4 | */
5 |
6 | @import url('resources/fonts/dejavu.css');
7 |
8 | body {
9 | background-color:#ffffff;
10 | color:#353833;
11 | font-family:'DejaVu Sans', Arial, Helvetica, sans-serif;
12 | font-size:14px;
13 | margin:0;
14 | }
15 | a:link, a:visited {
16 | text-decoration:none;
17 | color:#4A6782;
18 | }
19 | a:hover, a:focus {
20 | text-decoration:none;
21 | color:#bb7a2a;
22 | }
23 | a:active {
24 | text-decoration:none;
25 | color:#4A6782;
26 | }
27 | a[name] {
28 | color:#353833;
29 | }
30 | a[name]:hover {
31 | text-decoration:none;
32 | color:#353833;
33 | }
34 | pre {
35 | font-family:'DejaVu Sans Mono', monospace;
36 | font-size:14px;
37 | }
38 | h1 {
39 | font-size:20px;
40 | }
41 | h2 {
42 | font-size:18px;
43 | }
44 | h3 {
45 | font-size:16px;
46 | font-style:italic;
47 | }
48 | h4 {
49 | font-size:13px;
50 | }
51 | h5 {
52 | font-size:12px;
53 | }
54 | h6 {
55 | font-size:11px;
56 | }
57 | ul {
58 | list-style-type:disc;
59 | }
60 | code, tt {
61 | font-family:'DejaVu Sans Mono', monospace;
62 | font-size:14px;
63 | padding-top:4px;
64 | margin-top:8px;
65 | line-height:1.4em;
66 | }
67 | dt code {
68 | font-family:'DejaVu Sans Mono', monospace;
69 | font-size:14px;
70 | padding-top:4px;
71 | }
72 | table tr td dt code {
73 | font-family:'DejaVu Sans Mono', monospace;
74 | font-size:14px;
75 | vertical-align:top;
76 | padding-top:4px;
77 | }
78 | sup {
79 | font-size:8px;
80 | }
81 | /*
82 | Document title and Copyright styles
83 | */
84 | .clear {
85 | clear:both;
86 | height:0px;
87 | overflow:hidden;
88 | }
89 | .aboutLanguage {
90 | float:right;
91 | padding:0px 21px;
92 | font-size:11px;
93 | z-index:200;
94 | margin-top:-9px;
95 | }
96 | .legalCopy {
97 | margin-left:.5em;
98 | }
99 | .bar a, .bar a:link, .bar a:visited, .bar a:active {
100 | color:#FFFFFF;
101 | text-decoration:none;
102 | }
103 | .bar a:hover, .bar a:focus {
104 | color:#bb7a2a;
105 | }
106 | .tab {
107 | background-color:#0066FF;
108 | color:#ffffff;
109 | padding:8px;
110 | width:5em;
111 | font-weight:bold;
112 | }
113 | /*
114 | Navigation bar styles
115 | */
116 | .bar {
117 | background-color:#4D7A97;
118 | color:#FFFFFF;
119 | padding:.8em .5em .4em .8em;
120 | height:auto;/*height:1.8em;*/
121 | font-size:11px;
122 | margin:0;
123 | }
124 | .topNav {
125 | background-color:#4D7A97;
126 | color:#FFFFFF;
127 | float:left;
128 | padding:0;
129 | width:100%;
130 | clear:right;
131 | height:2.8em;
132 | padding-top:10px;
133 | overflow:hidden;
134 | font-size:12px;
135 | }
136 | .bottomNav {
137 | margin-top:10px;
138 | background-color:#4D7A97;
139 | color:#FFFFFF;
140 | float:left;
141 | padding:0;
142 | width:100%;
143 | clear:right;
144 | height:2.8em;
145 | padding-top:10px;
146 | overflow:hidden;
147 | font-size:12px;
148 | }
149 | .subNav {
150 | background-color:#dee3e9;
151 | float:left;
152 | width:100%;
153 | overflow:hidden;
154 | font-size:12px;
155 | }
156 | .subNav div {
157 | clear:left;
158 | float:left;
159 | padding:0 0 5px 6px;
160 | text-transform:uppercase;
161 | }
162 | ul.navList, ul.subNavList {
163 | float:left;
164 | margin:0 25px 0 0;
165 | padding:0;
166 | }
167 | ul.navList li{
168 | list-style:none;
169 | float:left;
170 | padding: 5px 6px;
171 | text-transform:uppercase;
172 | }
173 | ul.subNavList li{
174 | list-style:none;
175 | float:left;
176 | }
177 | .topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited {
178 | color:#FFFFFF;
179 | text-decoration:none;
180 | text-transform:uppercase;
181 | }
182 | .topNav a:hover, .bottomNav a:hover {
183 | text-decoration:none;
184 | color:#bb7a2a;
185 | text-transform:uppercase;
186 | }
187 | .navBarCell1Rev {
188 | background-color:#F8981D;
189 | color:#253441;
190 | margin: auto 5px;
191 | }
192 | .skipNav {
193 | position:absolute;
194 | top:auto;
195 | left:-9999px;
196 | overflow:hidden;
197 | }
198 | /*
199 | Page header and footer styles
200 | */
201 | .header, .footer {
202 | clear:both;
203 | margin:0 20px;
204 | padding:5px 0 0 0;
205 | }
206 | .indexHeader {
207 | margin:10px;
208 | position:relative;
209 | }
210 | .indexHeader span{
211 | margin-right:15px;
212 | }
213 | .indexHeader h1 {
214 | font-size:13px;
215 | }
216 | .title {
217 | color:#2c4557;
218 | margin:10px 0;
219 | }
220 | .subTitle {
221 | margin:5px 0 0 0;
222 | }
223 | .header ul {
224 | margin:0 0 15px 0;
225 | padding:0;
226 | }
227 | .footer ul {
228 | margin:20px 0 5px 0;
229 | }
230 | .header ul li, .footer ul li {
231 | list-style:none;
232 | font-size:13px;
233 | }
234 | /*
235 | Heading styles
236 | */
237 | div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 {
238 | background-color:#dee3e9;
239 | border:1px solid #d0d9e0;
240 | margin:0 0 6px -8px;
241 | padding:7px 5px;
242 | }
243 | ul.blockList ul.blockList ul.blockList li.blockList h3 {
244 | background-color:#dee3e9;
245 | border:1px solid #d0d9e0;
246 | margin:0 0 6px -8px;
247 | padding:7px 5px;
248 | }
249 | ul.blockList ul.blockList li.blockList h3 {
250 | padding:0;
251 | margin:15px 0;
252 | }
253 | ul.blockList li.blockList h2 {
254 | padding:0px 0 20px 0;
255 | }
256 | /*
257 | Page layout container styles
258 | */
259 | .contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer {
260 | clear:both;
261 | padding:10px 20px;
262 | position:relative;
263 | }
264 | .indexContainer {
265 | margin:10px;
266 | position:relative;
267 | font-size:12px;
268 | }
269 | .indexContainer h2 {
270 | font-size:13px;
271 | padding:0 0 3px 0;
272 | }
273 | .indexContainer ul {
274 | margin:0;
275 | padding:0;
276 | }
277 | .indexContainer ul li {
278 | list-style:none;
279 | padding-top:2px;
280 | }
281 | .contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt {
282 | font-size:12px;
283 | font-weight:bold;
284 | margin:10px 0 0 0;
285 | color:#4E4E4E;
286 | }
287 | .contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd {
288 | margin:5px 0 10px 0px;
289 | font-size:14px;
290 | font-family:'DejaVu Sans Mono',monospace;
291 | }
292 | .serializedFormContainer dl.nameValue dt {
293 | margin-left:1px;
294 | font-size:1.1em;
295 | display:inline;
296 | font-weight:bold;
297 | }
298 | .serializedFormContainer dl.nameValue dd {
299 | margin:0 0 0 1px;
300 | font-size:1.1em;
301 | display:inline;
302 | }
303 | /*
304 | List styles
305 | */
306 | ul.horizontal li {
307 | display:inline;
308 | font-size:0.9em;
309 | }
310 | ul.inheritance {
311 | margin:0;
312 | padding:0;
313 | }
314 | ul.inheritance li {
315 | display:inline;
316 | list-style:none;
317 | }
318 | ul.inheritance li ul.inheritance {
319 | margin-left:15px;
320 | padding-left:15px;
321 | padding-top:1px;
322 | }
323 | ul.blockList, ul.blockListLast {
324 | margin:10px 0 10px 0;
325 | padding:0;
326 | }
327 | ul.blockList li.blockList, ul.blockListLast li.blockList {
328 | list-style:none;
329 | margin-bottom:15px;
330 | line-height:1.4;
331 | }
332 | ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList {
333 | padding:0px 20px 5px 10px;
334 | border:1px solid #ededed;
335 | background-color:#f8f8f8;
336 | }
337 | ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList {
338 | padding:0 0 5px 8px;
339 | background-color:#ffffff;
340 | border:none;
341 | }
342 | ul.blockList ul.blockList ul.blockList ul.blockList li.blockList {
343 | margin-left:0;
344 | padding-left:0;
345 | padding-bottom:15px;
346 | border:none;
347 | }
348 | ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast {
349 | list-style:none;
350 | border-bottom:none;
351 | padding-bottom:0;
352 | }
353 | table tr td dl, table tr td dl dt, table tr td dl dd {
354 | margin-top:0;
355 | margin-bottom:1px;
356 | }
357 | /*
358 | Table styles
359 | */
360 | .overviewSummary, .memberSummary, .typeSummary, .useSummary, .constantsSummary, .deprecatedSummary {
361 | width:100%;
362 | border-left:1px solid #EEE;
363 | border-right:1px solid #EEE;
364 | border-bottom:1px solid #EEE;
365 | }
366 | .overviewSummary, .memberSummary {
367 | padding:0px;
368 | }
369 | .overviewSummary caption, .memberSummary caption, .typeSummary caption,
370 | .useSummary caption, .constantsSummary caption, .deprecatedSummary caption {
371 | position:relative;
372 | text-align:left;
373 | background-repeat:no-repeat;
374 | color:#253441;
375 | font-weight:bold;
376 | clear:none;
377 | overflow:hidden;
378 | padding:0px;
379 | padding-top:10px;
380 | padding-left:1px;
381 | margin:0px;
382 | white-space:pre;
383 | }
384 | .overviewSummary caption a:link, .memberSummary caption a:link, .typeSummary caption a:link,
385 | .useSummary caption a:link, .constantsSummary caption a:link, .deprecatedSummary caption a:link,
386 | .overviewSummary caption a:hover, .memberSummary caption a:hover, .typeSummary caption a:hover,
387 | .useSummary caption a:hover, .constantsSummary caption a:hover, .deprecatedSummary caption a:hover,
388 | .overviewSummary caption a:active, .memberSummary caption a:active, .typeSummary caption a:active,
389 | .useSummary caption a:active, .constantsSummary caption a:active, .deprecatedSummary caption a:active,
390 | .overviewSummary caption a:visited, .memberSummary caption a:visited, .typeSummary caption a:visited,
391 | .useSummary caption a:visited, .constantsSummary caption a:visited, .deprecatedSummary caption a:visited {
392 | color:#FFFFFF;
393 | }
394 | .overviewSummary caption span, .memberSummary caption span, .typeSummary caption span,
395 | .useSummary caption span, .constantsSummary caption span, .deprecatedSummary caption span {
396 | white-space:nowrap;
397 | padding-top:5px;
398 | padding-left:12px;
399 | padding-right:12px;
400 | padding-bottom:7px;
401 | display:inline-block;
402 | float:left;
403 | background-color:#F8981D;
404 | border: none;
405 | height:16px;
406 | }
407 | .memberSummary caption span.activeTableTab span {
408 | white-space:nowrap;
409 | padding-top:5px;
410 | padding-left:12px;
411 | padding-right:12px;
412 | margin-right:3px;
413 | display:inline-block;
414 | float:left;
415 | background-color:#F8981D;
416 | height:16px;
417 | }
418 | .memberSummary caption span.tableTab span {
419 | white-space:nowrap;
420 | padding-top:5px;
421 | padding-left:12px;
422 | padding-right:12px;
423 | margin-right:3px;
424 | display:inline-block;
425 | float:left;
426 | background-color:#4D7A97;
427 | height:16px;
428 | }
429 | .memberSummary caption span.tableTab, .memberSummary caption span.activeTableTab {
430 | padding-top:0px;
431 | padding-left:0px;
432 | padding-right:0px;
433 | background-image:none;
434 | float:none;
435 | display:inline;
436 | }
437 | .overviewSummary .tabEnd, .memberSummary .tabEnd, .typeSummary .tabEnd,
438 | .useSummary .tabEnd, .constantsSummary .tabEnd, .deprecatedSummary .tabEnd {
439 | display:none;
440 | width:5px;
441 | position:relative;
442 | float:left;
443 | background-color:#F8981D;
444 | }
445 | .memberSummary .activeTableTab .tabEnd {
446 | display:none;
447 | width:5px;
448 | margin-right:3px;
449 | position:relative;
450 | float:left;
451 | background-color:#F8981D;
452 | }
453 | .memberSummary .tableTab .tabEnd {
454 | display:none;
455 | width:5px;
456 | margin-right:3px;
457 | position:relative;
458 | background-color:#4D7A97;
459 | float:left;
460 |
461 | }
462 | .overviewSummary td, .memberSummary td, .typeSummary td,
463 | .useSummary td, .constantsSummary td, .deprecatedSummary td {
464 | text-align:left;
465 | padding:0px 0px 12px 10px;
466 | }
467 | th.colOne, th.colFirst, th.colLast, .useSummary th, .constantsSummary th,
468 | td.colOne, td.colFirst, td.colLast, .useSummary td, .constantsSummary td{
469 | vertical-align:top;
470 | padding-right:0px;
471 | padding-top:8px;
472 | padding-bottom:3px;
473 | }
474 | th.colFirst, th.colLast, th.colOne, .constantsSummary th {
475 | background:#dee3e9;
476 | text-align:left;
477 | padding:8px 3px 3px 7px;
478 | }
479 | td.colFirst, th.colFirst {
480 | white-space:nowrap;
481 | font-size:13px;
482 | }
483 | td.colLast, th.colLast {
484 | font-size:13px;
485 | }
486 | td.colOne, th.colOne {
487 | font-size:13px;
488 | }
489 | .overviewSummary td.colFirst, .overviewSummary th.colFirst,
490 | .useSummary td.colFirst, .useSummary th.colFirst,
491 | .overviewSummary td.colOne, .overviewSummary th.colOne,
492 | .memberSummary td.colFirst, .memberSummary th.colFirst,
493 | .memberSummary td.colOne, .memberSummary th.colOne,
494 | .typeSummary td.colFirst{
495 | width:25%;
496 | vertical-align:top;
497 | }
498 | td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover {
499 | font-weight:bold;
500 | }
501 | .tableSubHeadingColor {
502 | background-color:#EEEEFF;
503 | }
504 | .altColor {
505 | background-color:#FFFFFF;
506 | }
507 | .rowColor {
508 | background-color:#EEEEEF;
509 | }
510 | /*
511 | Content styles
512 | */
513 | .description pre {
514 | margin-top:0;
515 | }
516 | .deprecatedContent {
517 | margin:0;
518 | padding:10px 0;
519 | }
520 | .docSummary {
521 | padding:0;
522 | }
523 |
524 | ul.blockList ul.blockList ul.blockList li.blockList h3 {
525 | font-style:normal;
526 | }
527 |
528 | div.block {
529 | font-size:14px;
530 | font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif;
531 | }
532 |
533 | td.colLast div {
534 | padding-top:0px;
535 | }
536 |
537 |
538 | td.colLast a {
539 | padding-bottom:3px;
540 | }
541 | /*
542 | Formatting effect styles
543 | */
544 | .sourceLineNo {
545 | color:green;
546 | padding:0 30px 0 0;
547 | }
548 | h1.hidden {
549 | visibility:hidden;
550 | overflow:hidden;
551 | font-size:10px;
552 | }
553 | .block {
554 | display:block;
555 | margin:3px 10px 2px 0px;
556 | color:#474747;
557 | }
558 | .deprecatedLabel, .descfrmTypeLabel, .memberNameLabel, .memberNameLink,
559 | .overrideSpecifyLabel, .packageHierarchyLabel, .paramLabel, .returnLabel,
560 | .seeLabel, .simpleTagLabel, .throwsLabel, .typeNameLabel, .typeNameLink {
561 | font-weight:bold;
562 | }
563 | .deprecationComment, .emphasizedPhrase, .interfaceName {
564 | font-style:italic;
565 | }
566 |
567 | div.block div.block span.deprecationComment, div.block div.block span.emphasizedPhrase,
568 | div.block div.block span.interfaceName {
569 | font-style:normal;
570 | }
571 |
572 | div.contentContainer ul.blockList li.blockList h2{
573 | padding-bottom:0px;
574 | }
575 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | macaca.java
6 | biz
7 | 1.1.18
8 | jar
9 |
10 | biz
11 | http://maven.apache.org
12 |
13 |
14 |
15 | maven-compiler-plugin
16 |
17 | 1.8
18 | 1.8
19 |
20 |
21 |
22 | org.apache.maven.plugins
23 | maven-checkstyle-plugin
24 | 2.17
25 |
26 |
27 | validate
28 | validate
29 |
30 | checkstyle.xml
31 | UTF-8
32 | true
33 | true
34 | true
35 |
36 |
37 | check
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 | UTF-8
47 |
48 |
49 |
50 |
51 | org.junit.jupiter
52 | junit-jupiter-api
53 | 5.6.0
54 | test
55 |
56 |
57 | macaca.webdriver.client
58 | macacaclient
59 | 2.0.24
60 |
61 |
62 |
63 |
64 |
65 |
66 | spring lib
67 | spring lib
68 | https://repo.spring.io/libs-release/
69 |
70 | true
71 |
72 |
73 | false
74 |
75 |
76 |
77 |
78 |
79 |
80 | bintray-orgz-macaca-java-biz
81 | orgz-macaca-java-biz
82 | https://api.bintray.com/maven/orgz/macaca-java-biz/biz/;publish=1
83 |
84 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/src/main/java/macaca/java/biz/AppCommonPage.java:
--------------------------------------------------------------------------------
1 | package macaca.java.biz;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * @author shixing & niaoshuai
7 | * @program: biz
8 | * @description: App Common function
9 | * @create: 2020-05-18 16:40
10 | **/
11 | public class AppCommonPage extends BasePage {
12 | private double appWidth;
13 | private double appHeight;
14 |
15 | public AppCommonPage(String pageDesc) {
16 | super(pageDesc);
17 | }
18 |
19 | public double getAppHeight() {
20 | return appHeight;
21 | }
22 |
23 | public void setAppHeight(double appHeight) {
24 | this.appHeight = appHeight;
25 | }
26 |
27 | public double getAppWidth() {
28 | return appWidth;
29 | }
30 |
31 | public void setAppWidth(double appWidth) {
32 | this.appWidth = appWidth;
33 | }
34 |
35 | @Override
36 | public BaseMacacaClient getDriver() {
37 | return super.getDriver();
38 | }
39 |
40 | @Override
41 | public void setDriver(BaseMacacaClient driver) {
42 | super.setDriver(driver);
43 | if (driver.curPlatform == BaseMacacaClient.PlatformType.ANDROID) {
44 | getPhoneSize();
45 | }
46 | }
47 |
48 | /**
49 | * 通过adb命令获取耍手机的分辨率
50 | */
51 | public void getPhoneSize() {
52 | // Physical size: 1080x1920
53 | String adb = "adb shell wm size";
54 | List logs = BaseUtils.exec2(adb);
55 | String flag = "Physical size: ";
56 | for (String log : logs) {
57 | int index = log.indexOf(flag);
58 | if (index >= 0) {
59 | String hvga = log.substring(flag.length());
60 | String[] hvgas = hvga.split("x");
61 | this.setAppWidth(Double.parseDouble(hvgas[0]));
62 | this.setAppHeight(Double.parseDouble(hvgas[1]));
63 | }
64 | }
65 | }
66 |
67 | /**
68 | * 使用坐标占比 通过adb进行拖动
69 | * @param starRatioX
70 | * @param starRatioY
71 | * @param fromRatioX
72 | * @param fromRatioY
73 | * @throws Exception
74 | */
75 | public void dragByRatio(double starRatioX, double starRatioY, double fromRatioX, double fromRatioY) throws Exception {
76 | if (driver.curPlatform == BaseMacacaClient.PlatformType.ANDROID) {
77 | double x = this.getAppWidth() * starRatioX;
78 | double y = this.getAppHeight() * starRatioY;
79 | double fX = this.getAppWidth() * fromRatioX;
80 | double fY = this.getAppHeight() * fromRatioY;
81 | // adb 拖动 命令
82 | String cmdString = "adb shell input swipe" + " " + x + " " + y + " " + fX + " " + fY;
83 | BaseUtils.exec2(cmdString);
84 | driver.sleep(500);
85 | }
86 | }
87 |
88 | }
89 |
--------------------------------------------------------------------------------
/src/main/java/macaca/java/biz/BaseErrorType.java:
--------------------------------------------------------------------------------
1 | package macaca.java.biz;
2 |
3 | public enum BaseErrorType {
4 |
5 | /**
6 | * 错误码根据自身需求分类
7 | */
8 | //业务相关
9 | FUNCTION_FAILED(3001, "其他异常--"),
10 | ELEMENT_NOT_FOUND(3004, "未找到控件"),
11 | PAGE_NOT_LOAD(3006, "页面未加载"),
12 | //平台相关
13 | INSTALL_FAIL(1011, "安装失败");
14 |
15 |
16 | private int id;
17 | private String desc;
18 |
19 | BaseErrorType(int id, String desc) {
20 | this.id = id;
21 | this.desc = desc;
22 | }
23 |
24 | public int getId() {
25 | return this.id;
26 | }
27 |
28 | public String getDesc() {
29 | return this.desc;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/macaca/java/biz/BasePage.java:
--------------------------------------------------------------------------------
1 | package macaca.java.biz;
2 |
3 |
4 | /**
5 | * 通用Page基类,用于页面的通用处理,比如页面返回以及其他
6 | *
7 | * @author xiulian.yin
8 | */
9 | public class BasePage {
10 |
11 | /**
12 | * antClient driver
13 | */
14 | public BaseMacacaClient driver;
15 |
16 | /**
17 | * page desc 页面描述,日志输出时会用到,用于对当前页面一个可辨识的描述信息
18 | */
19 | public String pageDesc;
20 |
21 |
22 | public BaseMacacaClient getDriver() {
23 | return driver;
24 | }
25 |
26 | public void setDriver(BaseMacacaClient driver) {
27 | this.driver = driver;
28 | }
29 |
30 | /**
31 | * 构造函数 使用此方法只指定了页面描述,如果对页面进行操作,还需手动指定driver对象
32 | *
33 | * @param pageDesc 当前页面描述
34 | */
35 | public BasePage(String pageDesc) {
36 | this.pageDesc = pageDesc;
37 | }
38 |
39 | /**
40 | * 构造函数
41 | *
42 | * @param pageDesc 页面描述信息
43 | * @param driver 在页面上的各种操作需要利用driver进行,需要将外部的driver指给当前Page
44 | */
45 | public BasePage(String pageDesc, BaseMacacaClient driver) {
46 | this.pageDesc = pageDesc;
47 | this.driver = driver;
48 | }
49 |
50 |
51 | /**
52 | * 判断当前页面是否已经加载(判断方式为给出一个唯一标识的控件,通过判断该控件是否已经显示来确认页面是否已经加载)
53 | *
54 | * @param bean 用于唯一标识当前页面的控件
55 | * @return true:已经显示, false:未显示
56 | */
57 | public boolean hasPageShown(CommonUIBean bean) {
58 | boolean flag = driver.isElementExistAfterWaiting(bean);
59 | return flag;
60 | }
61 |
62 |
63 | }
64 |
--------------------------------------------------------------------------------
/src/main/java/macaca/java/biz/BaseUtils.java:
--------------------------------------------------------------------------------
1 | package macaca.java.biz;
2 |
3 | import java.io.BufferedInputStream;
4 | import java.io.BufferedReader;
5 | import java.io.File;
6 | import java.io.FileInputStream;
7 | import java.io.InputStreamReader;
8 | import java.math.BigInteger;
9 | import java.security.MessageDigest;
10 | import java.util.ArrayList;
11 | import java.util.List;
12 |
13 | public class BaseUtils {
14 |
15 | /**
16 | * 执行系统adb命令
17 | *
18 | * @param cmd 要执行的命令
19 | * 比如要执行adb命令 ,可以使用BaseUtils.exec("adb shell pm clear yourapp");
20 | * @return List
21 | */
22 | public static List exec2(String cmd) {
23 |
24 | // 将adb命令替换为系统安卓环境变量下的adb
25 | if (cmd.startsWith("adb")) {
26 | String androidHomePath = System.getenv("ANDROID_HOME");
27 | String adbPath = androidHomePath + "/platform-tools/adb";
28 | cmd = cmd.replace("adb", adbPath);
29 | }
30 |
31 | ResultGenerator.customLog("执行系统命令", cmd);
32 | Runtime run = Runtime.getRuntime(); //返回与当前 Java 应用程序相关的运行时对象
33 | List lines = new ArrayList();
34 | try {
35 | Process p = run.exec(cmd); // 启动另一个进程来执行命令
36 | BufferedInputStream in = new BufferedInputStream(p.getInputStream());
37 | BufferedReader inBr = new BufferedReader(new InputStreamReader(in));
38 | String line;
39 | while ((line = inBr.readLine()) != null) {
40 | lines.add(line);
41 | }
42 | inBr.close();
43 | in.close();
44 | } catch (Exception e) {
45 | ResultGenerator.customLog("命令执行异常", e.getMessage());
46 | }
47 | return lines;
48 | }
49 |
50 | /**
51 | * 删除app
52 | * Support: Android ios
53 | * 注:ios设备使用该方法时需提前在本机安装命令行工具ideviceinstaller,安装方法:brew install ideviceinstaller
54 | *
55 | * @param deviceType 设备类型 ios,android
56 | * @param deviceId 设备id,当存在多个设备时需指定设备id,如果只有一台设备,可以不必指定,ios:udid
57 | * @param app Android:apk的包名 iOS:app的bundleId
58 | */
59 | public static void uninstallApp(String deviceType, String deviceId, String app) {
60 | if (deviceType == "android") {
61 |
62 | if (isStringNotNull(deviceId)) {
63 | exec2("adb -s " + deviceId + " uninstall " + app);
64 | } else {
65 | exec2("adb uninstall " + app);
66 | }
67 |
68 | } else if (deviceType == "ios") {
69 |
70 | if (isStringNotNull(deviceId)) {
71 | exec2("/usr/local/bin/ideviceinstaller -u " + deviceId + " -U " + app);
72 | } else {
73 | exec2("/usr/local/bin/ideviceinstaller -U " + app);
74 | }
75 | }
76 |
77 |
78 | }
79 |
80 | /**
81 | * 安装app
82 | * Support: Android ios
83 | * 注:ios设备使用该方法时需提前在本机安装命令行工具ideviceinstaller,安装方法:brew install ideviceinstaller
84 | *
85 | * @param deviceType 设备类型 ios,android
86 | * @param deviceId 设备id,当存在多个设备时需指定设备id,如果只有一台设备,可以不必指定,ios:udid
87 | * @param packagePath 安装包路径 Android:.apk,ios:.ipa
88 | */
89 | public static void deviceInstaller(String deviceType, String deviceId, String packagePath) {
90 | if (deviceType == "android") {
91 |
92 | installApp(deviceId, packagePath);
93 |
94 | } else if (deviceType == "ios") {
95 |
96 | if (isStringNotNull(deviceId)) {
97 | exec2("/usr/local/bin/ideviceinstaller -u " + deviceId + " -i " + packagePath);
98 | } else {
99 | exec2("/usr/local/bin/ideviceinstaller -i " + packagePath);
100 | }
101 | }
102 |
103 |
104 | }
105 |
106 | /**
107 | * 启动app
108 | * Support: Android ios
109 | * 注:ios设备使用该方法时需提前在本机安装命令行工具libimobiledevice,
110 | * 安装方法:前往https://github.com/libimobiledevice/libimobiledevice
111 | * 将项目下载到本地,按照README进行配置、编译安装即可
112 | *
113 | * @param deviceType 设备类型 ios,android
114 | * @param deviceId 设备id,当存在多个设备时需指定设备id,如果只有一台设备,可以不必指定,ios:udid
115 | * @param packageName for Android,要启动app的packageName,与initDriver时设置的desiredCapabilities一致
116 | * @param activityName for Android,要启动app的activityName,与initDriver时设置的desiredCapabilities一致
117 | * @param bundleId for ios,要启动app的bundleId
118 | * @throws InterruptedException 中断异常
119 | */
120 | public static void launchApp(String deviceType, String deviceId, String packageName, String activityName, String bundleId) throws Exception {
121 | if (deviceType == "android") {
122 | startApp(deviceId, packageName, activityName);
123 | } else if (deviceType == "ios") {
124 | if (isStringNotNull(deviceId)) {
125 | exec2("/usr/local/bin/idevicedebug -u " + deviceId + " run " + bundleId);
126 | exec2("pkill idevicedebug");
127 | } else {
128 | exec2("/usr/local/bin/idevicedebug run " + bundleId);
129 | exec2("pkill idevicedebug");
130 | }
131 |
132 | }
133 | }
134 |
135 | /**
136 | * 安装app
137 | * Support: Android Only
138 | *
139 | * @param deviceId 设备id,当存在多个设备时需指定设备id,如果只有一台设备,可以不必指定
140 | * @param apkPath 安装包路径
141 | */
142 | public static void installApp(String deviceId, String apkPath) {
143 | if (isStringNotNull(deviceId)) {
144 | exec2("adb -s " + deviceId + "install " + apkPath);
145 | } else {
146 | exec2("adb install" + apkPath);
147 | }
148 | }
149 |
150 | /**
151 | * 启动app
152 | * Support: Android only
153 | *
154 | * @param deviceId 设备id,当存在多个设备时需指定设备id,如果只有一台设备,可以不必指定
155 | * @param packageName 要启动app的packageName,与initDriver时设置的desiredCapabilities一致
156 | * @param activityName 要启动app的activityName,与initDriver时设置的desiredCapabilities一致
157 | */
158 | public static void startApp(String deviceId, String packageName, String activityName) {
159 | if (isStringNotNull(deviceId)) {
160 | exec2("adb -s " + deviceId + " shell am start -S -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -f 0x10200000 -n " + packageName + "/" + activityName);
161 | } else {
162 | exec2("adb shell am start -S -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -f 0x10200000 -n " + packageName + "/" + activityName);
163 | }
164 |
165 | }
166 |
167 | /**
168 | * 清理app
169 | * Support: Android only
170 | *
171 | * @param deviceId 设备id,当存在多个设备时需指定设备id,如果只有一台设备,可以不必指定
172 | * @param packageName 要启动app的packageName,与initDriver时设置的desiredCapabilities一致
173 | */
174 | public static void clearApp(String deviceId, String packageName) {
175 |
176 | if (isStringNotNull(deviceId)) {
177 | exec2("adb -s " + deviceId + " shell pm clear " + packageName);
178 | } else {
179 | exec2("adb shell pm clear " + packageName);
180 | }
181 |
182 | }
183 |
184 | /**
185 | * 杀死app
186 | * Support: Android only
187 | *
188 | * @param deviceId 设备id,当存在多个设备时需指定设备id,如果只有一台设备,可以不必指定
189 | * @param packageName 要启动app的packageName,与initDriver时设置的desiredCapabilities一致
190 | */
191 | public static void forceStopApp(String deviceId, String packageName) {
192 |
193 | if (isStringNotNull(deviceId)) {
194 | exec2("adb -s " + deviceId + " shell am force-stop " + packageName);
195 | } else {
196 | exec2("adb shell am force-stop " + packageName);
197 | }
198 |
199 | }
200 |
201 | /**
202 | * 获取文件md5
203 | *
204 | * @param file 要处理的文件对象
205 | * @return 文件MD5后的结果
206 | */
207 | public static String getFileMD5(File file) {
208 | if (!file.isFile()) {
209 | return null;
210 | }
211 | MessageDigest digest = null;
212 | FileInputStream in = null;
213 | byte[] buffer = new byte[1024];
214 | int len;
215 | try {
216 | digest = MessageDigest.getInstance("MD5");
217 | in = new FileInputStream(file);
218 | while ((len = in.read(buffer, 0, 1024)) != -1) {
219 | digest.update(buffer, 0, len);
220 | }
221 | in.close();
222 | } catch (Exception e) {
223 | e.printStackTrace();
224 | return null;
225 | }
226 | BigInteger bigInt = new BigInteger(1, digest.digest());
227 | return bigInt.toString(16);
228 | }
229 |
230 |
231 | public static boolean isStringNotNull(String str) {
232 | if (str == null || str.length() == 0) {
233 | return false;
234 | }
235 |
236 | return true;
237 | }
238 |
239 | /**
240 | * 通过adb命令模拟用户输入
241 | *
242 | * @param content 要输入的内容
243 | * 注意:建议输入英文,输入中文时由于系统问题会导致输入无效
244 | */
245 | public static void inputText(String content) {
246 |
247 | if (isStringNotNull(content)) {
248 |
249 | BaseUtils.exec2("adb shell input text " + content);
250 | }
251 | }
252 |
253 | /**
254 | * 通过adb命令获取输入软键盘的状态
255 | * 1、mInputShown=true 则判断软键盘弹出
256 | * 2、mInputShown=false 则判断软键盘隐藏
257 | * 3、执行命令失败的情况下,默认返回false
258 | *
259 | * @return boolean 软键盘显示:true,软键盘隐藏:false
260 | */
261 | public static boolean isSoftKeyboardDisplay() {
262 |
263 | List result = BaseUtils.exec2("adb shell dumpsys input_method | grep mInputShown=");
264 | if (result == null || result.size() == 0) {
265 | //执行命令失败,获取不到软键盘的输入状态关键字
266 | return false;
267 | } else {
268 | for (String line : result) {
269 | if (line.contains("mInputShown=true")) {
270 | //执行结果包含"mInputShown=true",则认为软键盘弹出
271 | return true;
272 | }
273 | }
274 | return false;
275 | }
276 | }
277 | }
278 |
--------------------------------------------------------------------------------
/src/main/java/macaca/java/biz/CommonUIBean.java:
--------------------------------------------------------------------------------
1 | package macaca.java.biz;
2 |
3 | import macaca.client.common.GetElementWay;
4 |
5 | public class CommonUIBean {
6 |
7 | protected GetElementWay androidBy; //id or xpath or name
8 | protected String androidValue;
9 | protected GetElementWay iosBy; //id or xpath or name
10 | protected String iosValue;
11 | protected int index = 0;
12 | public String elementDesc; // 控件描述
13 |
14 | /**
15 | * 当安卓 ios两个平台对应同一控件的获取方式不一致时使用本构造函数
16 | *
17 | * @param androidBy 获取安卓对应控件的方式
18 | * @param androidValue 获取安卓对应控件的值
19 | * @param iosBy 获取ios对应控件的方式
20 | * @param iosValue 获取ios对应控件的值
21 | * @param elementDesc 控件描述文案
22 | */
23 | public CommonUIBean(GetElementWay androidBy, String androidValue, GetElementWay iosBy, String iosValue, String elementDesc) {
24 | this.androidBy = androidBy;
25 | this.androidValue = androidValue;
26 | this.iosBy = iosBy;
27 | this.iosValue = iosValue;
28 | this.elementDesc = elementDesc;
29 | }
30 |
31 | /**
32 | * 当安卓 ios两个平台对应同一控件的获取方式不一致时使用本构造函数
33 | *
34 | * @param androidBy 获取安卓对应控件的方式
35 | * @param androidValue 获取安卓对应控件的值
36 | * @param iosBy 获取ios对应控件的方式
37 | * @param iosValue 获取ios对应控件的值
38 | * @param index 控件索引,当存在多个控件时,用index表示要查找的控件的index
39 | * @param elementDesc 控件描述文案
40 | */
41 | public CommonUIBean(GetElementWay androidBy, String androidValue, GetElementWay iosBy, String iosValue, int index, String elementDesc) {
42 | this.androidBy = androidBy;
43 | this.androidValue = androidValue;
44 | this.iosBy = iosBy;
45 | this.iosValue = iosValue;
46 | this.elementDesc = elementDesc;
47 | this.index = index;
48 | }
49 |
50 | /**
51 | * 构造函数,用于ios android两个平台获取UI一致的情况
52 | *
53 | * @param commonBy 统一获取控件方式
54 | * @param commonValue 统一获取控件值
55 | * @param elementDesc 控件描述文案
56 | */
57 | public CommonUIBean(GetElementWay commonBy, String commonValue, String elementDesc) {
58 | this.androidBy = commonBy;
59 | this.androidValue = commonValue;
60 | this.iosBy = commonBy;
61 | this.iosValue = commonValue;
62 | this.elementDesc = elementDesc;
63 | }
64 |
65 | /**
66 | * 构造函数,用于ios android两个平台获取UI一致的情况
67 | *
68 | * @param commonBy 统一获取控件方式
69 | * @param commonValue 统一获取控件值
70 | * @param elementDesc 控件描述文案
71 | * @param index 控件索引,当存在多个控件时,用index表示要查找的控件的index
72 | */
73 | public CommonUIBean(GetElementWay commonBy, String commonValue, int index, String elementDesc) {
74 | this.androidBy = commonBy;
75 | this.androidValue = commonValue;
76 | this.iosBy = commonBy;
77 | this.iosValue = commonValue;
78 | this.elementDesc = elementDesc;
79 | this.index = index;
80 | }
81 |
82 |
83 | public GetElementWay getAndroidBy() {
84 | return androidBy;
85 | }
86 |
87 | public void setAndroidBy(GetElementWay androidBy) {
88 | this.androidBy = androidBy;
89 | }
90 |
91 | public String getAndroidValue() {
92 | return androidValue;
93 | }
94 |
95 | public void setAndroidValue(String androidValue) {
96 | this.androidValue = androidValue;
97 | }
98 |
99 | public GetElementWay getIosBy() {
100 | return iosBy;
101 | }
102 |
103 | public void setIosBy(GetElementWay iosBy) {
104 | this.iosBy = iosBy;
105 | }
106 |
107 | public String getIosValue() {
108 | return iosValue;
109 | }
110 |
111 | public void setIosValue(String iosValue) {
112 | this.iosValue = iosValue;
113 | }
114 |
115 | public void setIndex(int index) {
116 | this.index = index;
117 | }
118 |
119 | public int getIndex() {
120 | return index;
121 | }
122 |
123 | public String getElementDesc() {
124 | return elementDesc;
125 | }
126 |
127 | public void setElementDesc(String elementDesc) {
128 | this.elementDesc = elementDesc;
129 | }
130 |
131 |
132 | }
133 |
--------------------------------------------------------------------------------
/src/main/java/macaca/java/biz/ResultGenerator.java:
--------------------------------------------------------------------------------
1 | package macaca.java.biz;
2 |
3 | import java.io.File;
4 | import java.io.FileNotFoundException;
5 | import java.io.FileOutputStream;
6 | import java.io.IOException;
7 | import java.text.SimpleDateFormat;
8 | import java.util.Date;
9 |
10 | public class ResultGenerator {
11 |
12 | public static final String NAME = "result.log";
13 | public static final String CUSTOM_LOG = "custom.log";
14 | public static final String SEPARATOR = "|";
15 | public static final String LINE_SEPARATOR = System.getProperty("line.separator");
16 |
17 | public static void write2File(String name, boolean append, String content) throws Exception {
18 | System.out.println(content);
19 | FileOutputStream fos = null;
20 | try {
21 | fos = new FileOutputStream(name, append);
22 | fos.write(content.getBytes());
23 | } catch (FileNotFoundException e) {
24 | e.printStackTrace();
25 | ResultGenerator.catchedException(e);
26 | } catch (IOException e) {
27 | e.printStackTrace();
28 | ResultGenerator.catchedException(e);
29 | } finally {
30 | if (fos != null) {
31 | fos.close();
32 | }
33 | }
34 | }
35 |
36 | /**
37 | * 清除log数据,包含result.log custom.log
38 | */
39 | public static void clearOldData() {
40 | File resultFile = new File(NAME);
41 | if (resultFile.exists() && resultFile.isFile()) {
42 | resultFile.delete();
43 | }
44 |
45 | File customLogFile = new File(CUSTOM_LOG);
46 | if (customLogFile.exists() && customLogFile.isFile()) {
47 | customLogFile.delete();
48 | }
49 | }
50 |
51 | /**
52 | * 成功时记录,desc是预留参数,目前随便填什么都可以
53 | *
54 | * @param action, 当前操作
55 | * @param desc, 描述,预留字段,可以设为空字符串
56 | */
57 | public static void success(String action, String desc) {
58 | //为了保证customLog的完整性,把resultLog的输出也打印到customLog上
59 | try {
60 | write2File(NAME, true, getStringDate() + "," + action + SEPARATOR + true + SEPARATOR + desc + LINE_SEPARATOR);
61 | write2File(CUSTOM_LOG, true, getStringDate() + "," + action + SEPARATOR + true + SEPARATOR + desc + LINE_SEPARATOR);
62 | } catch (Exception e) {
63 | ResultGenerator.catchedException(e);
64 | }
65 |
66 | }
67 |
68 | /**
69 | * 页面加载成功日志记录
70 | *
71 | * @param page 当前page对象
72 | */
73 | public static void loadPageSucc(BasePage page) {
74 | success(page.pageDesc, "页面加载成功");
75 | }
76 |
77 | /**
78 | * 页面加载失败时生成日志记录
79 | *
80 | * @param page 当前页面对象
81 | */
82 | public static void loadPageFail(BasePage page) {
83 | fail(page.pageDesc, "页面加载失败", BaseErrorType.PAGE_NOT_LOAD);
84 | }
85 |
86 | /**
87 | * 控件查找失败时生成日志记录
88 | *
89 | * @param targetElement 目标UI控件
90 | */
91 | public static void findElementFail(CommonUIBean targetElement) {
92 | // 因为控件没查到不一定意味着这个case是失败的,但如果用fail就会导致整个case标记为失败,因此这里调用success方法
93 | customLog(targetElement.elementDesc, "控件不存在");
94 | }
95 |
96 | /**
97 | * 进入catch Exception方法时触发日志记录
98 | */
99 | public static void catchedException(Exception e) {
100 | // e.printStackTrace();
101 | customLog("异常捕捉", e.getMessage());
102 | }
103 | //action|false|desc|type(code) ---> action|false|type|desc
104 |
105 | /**
106 | * @param action 关键动作描述
107 | * @param desc 错误描述
108 | * @param type 错误类型, 必须选择一个错误类型
109 | */
110 | public static void fail(String action, String desc, BaseErrorType type) {
111 | try {
112 | write2File(NAME, true, getStringDate() + "," + action + SEPARATOR + false + SEPARATOR + desc + SEPARATOR + type.getId() + LINE_SEPARATOR);
113 | write2File(CUSTOM_LOG, true, getStringDate() + "," + action + SEPARATOR + false + SEPARATOR + desc + SEPARATOR + type.getId() + LINE_SEPARATOR);
114 | } catch (Exception e) {
115 | e.printStackTrace();
116 | }
117 | }
118 |
119 | /**
120 | * 自定义日志输出
121 | *
122 | * @param action 动作信息
123 | * @param desc 自定义描述信息
124 | */
125 | public static void customLog(String action, String desc) {
126 |
127 | try {
128 | write2File(CUSTOM_LOG, true, getStringDate() + "," + action + SEPARATOR + desc + LINE_SEPARATOR);
129 | } catch (Exception e) {
130 | ResultGenerator.catchedException(e);
131 | }
132 |
133 | }
134 |
135 | public static void main(String[] args) {
136 | // success("登录成功", "");
137 | }
138 |
139 |
140 | /**
141 | * @return 返回字符串格式 yyyy-MM-dd HH:mm:ss
142 | */
143 | public static String getStringDate() {
144 | Date currentTime = new Date();
145 | SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
146 | String dateString = formatter.format(currentTime);
147 | return dateString;
148 | }
149 |
150 | }
151 |
--------------------------------------------------------------------------------
/src/main/java/macaca/java/biz/WebCommonPage.java:
--------------------------------------------------------------------------------
1 | package macaca.java.biz;
2 |
3 | import macaca.client.commands.Element;
4 | import macaca.client.common.GetElementWay;
5 | import java.awt.Toolkit;
6 | import java.awt.Robot;
7 | import java.awt.datatransfer.StringSelection;
8 | import java.awt.event.KeyEvent;
9 | import java.util.List;
10 | import java.util.Random;
11 |
12 | /**
13 | * @author shixing & niaoshuiai
14 | * @program: biz
15 | * @description: web common function
16 | * @create: 2020-05-18 16:41
17 | **/
18 | public class WebCommonPage extends BasePage {
19 | public WebCommonPage(String pageDesc) {
20 | super(pageDesc);
21 | }
22 | /**
23 | * 获取 List
24 | * @param bean
25 | * @return
26 | * @throws Exception
27 | */
28 | public List getElements(CommonUIBean bean) throws Exception {
29 | driver.sleep(1000);
30 | class FindElements {
31 | int waitTime = 15;
32 | List findAction(GetElementWay getElementWay, String value) throws Exception {
33 | List els = null;
34 | while (waitTime > 0) {
35 | switch (getElementWay) {
36 | case ID:
37 | els = driver.elementsById(value);
38 | break;
39 | case CSS:
40 | els = driver.elementsByCss(value);
41 | break;
42 | case NAME:
43 | els = driver.elementsByName(value);
44 | break;
45 | case XPATH:
46 | els = driver.elementsByXPath(value);
47 | break;
48 | case CLASS_NAME:
49 | els = driver.elementsByClassName(value);
50 | break;
51 | case LINK_TEXT:
52 | els = driver.elementsByLinkText(value);
53 | break;
54 | case PARTIAL_LINK_TEXT:
55 | els = driver.elementsByPartialLinkText(value);
56 | break;
57 | case TAG_NAME:
58 | els = driver.elementsByTagName(value);
59 | break;
60 | default:
61 |
62 | break;
63 | }
64 |
65 | if (els == null) {
66 | driver.sleep(1000);
67 | waitTime--;
68 | } else {
69 | return els;
70 | }
71 | }
72 | if (driver.curPlatform == BaseMacacaClient.PlatformType.ANDROID) {
73 | ResultGenerator.customLog(bean.elementDesc, "没有找到该元素,元素 : " + bean.getAndroidValue());
74 | } else {
75 | ResultGenerator.customLog(bean.elementDesc, "没有找到该元素,元素值: " + bean.getIosValue());
76 | }
77 | return null;
78 | }
79 | }
80 | FindElements findElements = new FindElements();
81 |
82 | // 根据对应类型,调用对应的方法
83 | return driver.curPlatform == BaseMacacaClient.PlatformType.ANDROID ? findElements.findAction(bean.getAndroidBy(), bean.getAndroidValue())
84 | :
85 | findElements.findAction(bean.getIosBy(), bean.getIosValue());
86 | }
87 |
88 |
89 | /**
90 | * 复选框 选择多个
91 | * @param checkboxByListBean
92 | * @throws Exception
93 | */
94 | public void checkboxSelect(CommonUIBean checkboxByListBean) throws Exception {
95 | driver.sleep(1000);
96 | List els = getElements(checkboxByListBean);
97 | int count = els.size();
98 | int random = randomInt(count - 1);
99 | for (int i = 0; i <= random; i++) {
100 | driver.onclickBeanAtIndex(checkboxByListBean, i);
101 | driver.sleep(800);
102 | }
103 | List newEls = getElements(checkboxByListBean);
104 | // 如果点击失败 ,则再次调用
105 | if (count == newEls.size()) {
106 | checkboxSelect(checkboxByListBean);
107 | }
108 | }
109 |
110 | /**
111 | * Radio 随机选择一个
112 | * @param radioByListBean
113 | * @throws Exception
114 | */
115 | public void radioSelect(CommonUIBean radioByListBean) throws Exception {
116 | //随机选择一个正确答案
117 | int i = getElements(radioByListBean).size() - 1;
118 | if (i <= 0) {
119 | //集合中包含单一元素处理
120 | driver.onclickBeanAtIndex(radioByListBean, randomInt(i + 1));
121 | }
122 | driver.onclickBeanAtIndex(radioByListBean, randomInt(i));
123 | driver.sleep(800);
124 | }
125 |
126 |
127 | /**
128 | * 拖动页面到底部
129 | *
130 | * @throws Exception
131 | */
132 | public void dragBottom() throws Exception {
133 | String js = "document.documentElement.scrollTop=100000";
134 | driver.execute(js);
135 | }
136 |
137 | /**
138 | * 拖动页面到底部
139 | *
140 | * @throws Exception
141 | */
142 | public void dragTop() throws Exception {
143 | String js = "document.documentElement.scrollTop=0";
144 | driver.execute(js);
145 | }
146 |
147 | /**
148 | * 拖动页面向右滑动,使用按键的方式。(点击,选中元素后,发送键盘指令进行滚动)
149 | * @param count 滚动次数
150 | * @param bean 以哪个元素为基础进行运动
151 | * @throws Exception
152 | */
153 | public void dragRight(int count, CommonUIBean bean) throws Exception {
154 | //首先定位到 页面的div 然后点击向右的方向按钮
155 | driver.onclickBean(bean);
156 | Robot robot = new Robot();
157 | driver.sleep(500);
158 | for (int i = 0; i <= count; i++) {
159 | robot.keyPress(KeyEvent.VK_RIGHT);
160 | robot.keyRelease(KeyEvent.VK_RIGHT);
161 | }
162 | }
163 | /**
164 | *
165 | * @param uploadBtnBean 上传控件CSS
166 | * @param filePath 上传文件名称
167 | * @param waitTime 上传完毕后等待时间。
168 | * @throws Exception
169 | */
170 | public void uploadFile(CommonUIBean uploadBtnBean, String filePath, int waitTime) throws Exception {
171 | ResultGenerator.customLog(filePath, "上传文件路径");
172 | driver.onclickBean(uploadBtnBean);
173 | uploadFileByRobot(filePath);
174 | driver.sleep(waitTime);
175 | }
176 |
177 | /**
178 | * 非input类型上传控件:robot方式
179 | * @param filePath
180 | */
181 | private static void uploadFileByRobot(String filePath) {
182 | //传入文件路径
183 | try {
184 | Thread.sleep(1000);
185 | // 指定图片的路径 :filepath
186 | StringSelection sel = new StringSelection(filePath);
187 | // 把图片文件路径复制到剪贴板
188 | Toolkit.getDefaultToolkit().getSystemClipboard().setContents(sel, null);
189 | ResultGenerator.customLog(sel.toString(), "selection");
190 | // 新建一个Robot类的对象
191 | Robot robot = new Robot();
192 | Thread.sleep(1000);
193 | // 按下回车
194 | robot.keyPress(KeyEvent.VK_ENTER);
195 | // 释放回车
196 | robot.keyRelease(KeyEvent.VK_ENTER);
197 | // 按下 CTRL+V
198 | robot.keyPress(KeyEvent.VK_CONTROL);
199 | robot.keyPress(KeyEvent.VK_V);
200 | // 释放 CTRL+V
201 | robot.keyRelease(KeyEvent.VK_CONTROL);
202 | robot.keyRelease(KeyEvent.VK_V);
203 | Thread.sleep(1000);
204 | // 点击回车 Enter
205 | robot.keyPress(KeyEvent.VK_ENTER);
206 | robot.keyRelease(KeyEvent.VK_ENTER);
207 | ResultGenerator.customLog("执行上传文件通过", "文件上传结果");
208 | } catch (Exception e) {
209 | ResultGenerator.customLog("执行上传文件失败", "文件上传结果");
210 | }
211 | }
212 |
213 |
214 |
215 | /**
216 | * 生成随机数
217 | * @param length
218 | * @return
219 | */
220 | private int randomInt(Integer length) {
221 | Random rm = new Random();
222 | if (length == 0) {
223 | return 0;
224 | } else {
225 | int i = rm.nextInt(length);
226 | return i;
227 | }
228 | }
229 | }
230 |
--------------------------------------------------------------------------------
/src/test/java/macaca/java/biz/AppTest.java:
--------------------------------------------------------------------------------
1 | package macaca.java.biz;
2 |
3 |
4 | import org.junit.jupiter.api.Assertions;
5 | import org.junit.jupiter.api.Test;
6 |
7 | /**
8 | * Unit test for simple App.
9 | */
10 | public class AppTest {
11 | @Test
12 | public void appTest() {
13 | Assertions.assertTrue(true);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------