├── .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 |
14 | 35 |
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 | 26 | 27 |
28 | 29 | 30 | 31 | 32 | 33 | 34 | 42 |
43 | 71 | 72 |
73 |

Constant Field Values

74 |

Contents

75 | 78 |
79 |
80 | 81 | 82 |

macaca.java.*

83 |
    84 |
  • 85 | 87 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 100 | 103 | 104 | 105 | 106 | 109 | 112 | 113 | 114 | 115 |
    macaca.java.biz.BaseMacacaClient 
    Modifier and TypeConstant FieldValue
    98 | 99 | public static final java.lang.StringAFTER_IMAGE_NAME 102 | "after.png"
    107 | 108 | public static final java.lang.StringBEFORE_IMAGE_NAME 111 | "before.png"
    116 |
  • 117 |
  • 118 | 120 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 133 | 134 | 135 | 136 | 137 | 140 | 141 | 142 | 143 | 144 | 147 | 148 | 149 | 150 | 151 |
    macaca.java.biz.ResultGenerator 
    Modifier and TypeConstant FieldValue
    131 | 132 | public static final java.lang.StringCUSTOM_LOG"custom.log"
    138 | 139 | public static final java.lang.StringNAME"result.log"
    145 | 146 | public static final java.lang.StringSEPARATOR"|"
    152 |
  • 153 |
154 |
155 | 156 |
157 | 158 | 159 | 160 | 161 | 162 | 163 | 171 |
172 | 200 | 201 | 202 | 203 | -------------------------------------------------------------------------------- /docs/deprecated-list.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Deprecated List 7 | 8 | 9 | 10 | 11 | 12 | 23 | 26 | 27 |
28 | 29 | 30 | 31 | 32 | 33 | 34 | 42 |
43 | 71 | 72 |
73 |

Deprecated API

74 |

Contents

75 | 78 |
79 | 111 | 112 |
113 | 114 | 115 | 116 | 117 | 118 | 119 | 127 |
128 | 156 | 157 | 158 | 159 | -------------------------------------------------------------------------------- /docs/help-doc.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | API Help 7 | 8 | 9 | 10 | 11 | 12 | 23 | 26 | 27 |
28 | 29 | 30 | 31 | 32 | 33 | 34 | 42 |
43 | 71 | 72 |
73 |

How This API Document Is Organized

74 |
This API (Application Programming Interface) document has pages corresponding to the items in 75 | the navigation bar, described as follows. 76 |
77 |
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 |
196 | 197 | 198 | 199 | 200 | 201 | 202 | 210 |
211 | 239 | 240 | 241 | 242 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Generated Documentation (Untitled) 7 | 60 | 61 | 62 | 64 | 66 | 67 | <noscript> 68 | <div>JavaScript is disabled on your browser.</div> 69 | </noscript> 70 | <h2>Frame Alert</h2> 71 | <p>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 <a href="macaca/java/biz/package-summary.html">Non-frame version</a>. 73 | </p> 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /docs/macaca/java/biz/App.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | App 7 | 8 | 9 | 10 | 11 | 12 | 29 | 32 | 33 |
34 | 35 | 36 | 37 | 38 | 39 | 40 | 48 |
49 | 93 | 94 | 95 |
96 |
macaca.java.biz
97 |

Class App

98 |
99 |
100 |
    101 |
  • java.lang.Object
  • 102 |
  • 103 |
      104 |
    • macaca.java.biz.App
    • 105 |
    106 |
  • 107 |
108 |
109 |
    110 |
  • 111 |
    112 |
    113 |
    public class App
    114 | extends java.lang.Object
    115 |
    Hello world!
    116 |
  • 117 |
118 |
119 |
120 |
    121 |
  • 122 | 123 |
      124 |
    • 125 | 126 | 127 |

      Constructor Summary

      128 | 130 | 131 | 132 | 133 | 134 | 135 | 138 | 139 |
      Constructors 
      Constructor and Description
      App()  137 |
      140 |
    • 141 |
    142 | 143 |
      144 |
    • 145 | 146 | 147 |

      Method Summary

      148 | 150 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 165 | 166 |
      All Methods Static Methods Concrete Methods 
      Modifier and TypeMethod and Description
      static voidmain(java.lang.String[] args)  164 |
      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 | 200 | 201 |
      202 |
    • 203 | 204 | 205 |

      Method Detail

      206 | 207 | 208 | 209 |
        210 |
      • 211 |

        main

        212 |
        public static void main(java.lang.String[] args)
        213 |
      • 214 |
      215 |
    • 216 |
    217 |
  • 218 |
219 |
220 |
221 | 222 | 223 |
224 | 225 | 226 | 227 | 228 | 229 | 230 | 238 |
239 | 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 | 32 | 33 |
34 | 35 | 36 | 37 | 38 | 39 | 40 | 48 |
49 | 95 | 96 | 97 |
98 |
macaca.java.biz
99 |

Enum BaseMacacaClient.GesturePinchType

100 |
101 |
102 |
    103 |
  • java.lang.Object
  • 104 |
  • 105 | 114 |
  • 115 |
116 |
117 | 137 |
138 |
139 |
    140 |
  • 141 | 142 |
      143 |
    • 144 | 145 | 146 |

      Enum Constant Summary

      147 | 149 | 150 | 151 | 152 | 153 | 154 | 157 | 158 | 159 | 162 | 163 |
      Enum Constants 
      Enum Constant and Description
      PINCH_IN  156 |
      PINCH_OUT  161 |
      164 |
    • 165 |
    166 | 167 |
      168 |
    • 169 | 170 | 171 |

      Method Summary

      172 | 174 | 180 | 181 | 182 | 183 | 184 | 185 | 189 | 194 | 195 | 196 | 200 | 206 | 207 |
      All Methods Static Methods Concrete Methods 
      Modifier and TypeMethod and Description
      static BaseMacacaClient.GesturePinchType 188 | valueOf(java.lang.String name) 191 |
      Returns the enum constant of this type with the specified name. 192 |
      193 |
      static BaseMacacaClient.GesturePinchType[] 199 | values() 202 |
      Returns an array containing the constants of this enum type, in 203 | the order they are declared. 204 |
      205 |
      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 |
        271 |
      • 272 |

        values

        273 |
        public static BaseMacacaClient.GesturePinchType[] values()
        276 |
        Returns an array containing the constants of this enum type, in 277 | the order they are declared. This method may be used to iterate 278 | over the constants as follows: 279 |
        280 | for (BaseMacacaClient.GesturePinchType c : BaseMacacaClient.GesturePinchType.values())
        281 |     System.out.println(c);
        282 | 
        283 |
        284 |
        285 |
        Returns:
        286 |
        an array containing the constants of this enum type, in the order they are 287 | declared 288 |
        289 |
        290 |
      • 291 |
      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 |
328 | 329 | 330 | 331 | 332 | 333 | 334 | 342 |
343 | 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 | 32 | 33 |
34 | 35 | 36 | 37 | 38 | 39 | 40 | 48 |
49 | 95 | 96 | 97 |
98 |
macaca.java.biz
99 |

Enum BaseMacacaClient.PlatformType

100 |
101 |
102 |
    103 |
  • java.lang.Object
  • 104 |
  • 105 | 114 |
  • 115 |
116 |
117 | 137 |
138 |
139 |
    140 |
  • 141 | 142 |
      143 |
    • 144 | 145 | 146 |

      Enum Constant Summary

      147 | 149 | 150 | 151 | 152 | 153 | 154 | 157 | 158 | 159 | 162 | 163 |
      Enum Constants 
      Enum Constant and Description
      ANDROID  156 |
      IOS  161 |
      164 |
    • 165 |
    166 | 167 |
      168 |
    • 169 | 170 | 171 |

      Method Summary

      172 | 174 | 180 | 181 | 182 | 183 | 184 | 185 | 188 | 193 | 194 | 195 | 198 | 204 | 205 |
      All Methods Static Methods Concrete Methods 
      Modifier and TypeMethod and Description
      static BaseMacacaClient.PlatformTypevalueOf(java.lang.String name) 190 |
      Returns the enum constant of this type with the specified name. 191 |
      192 |
      static BaseMacacaClient.PlatformType[]values() 200 |
      Returns an array containing the constants of this enum type, in 201 | the order they are declared. 202 |
      203 |
      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 |
        269 |
      • 270 |

        values

        271 |
        public static BaseMacacaClient.PlatformType[] values()
        274 |
        Returns an array containing the constants of this enum type, in 275 | the order they are declared. This method may be used to iterate 276 | over the constants as follows: 277 |
        278 | for (BaseMacacaClient.PlatformType c : BaseMacacaClient.PlatformType.values())
        279 |     System.out.println(c);
        280 | 
        281 |
        282 |
        283 |
        Returns:
        284 |
        an array containing the constants of this enum type, in the order they are 285 | declared 286 |
        287 |
        288 |
      • 289 |
      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 |
326 | 327 | 328 | 329 | 330 | 331 | 332 | 340 |
341 | 387 | 388 | 389 | 390 | -------------------------------------------------------------------------------- /docs/macaca/java/biz/BasePage.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | BasePage 7 | 8 | 9 | 10 | 11 | 12 | 29 | 32 | 33 |
34 | 35 | 36 | 37 | 38 | 39 | 40 | 48 |
49 | 94 | 95 | 96 |
97 |
macaca.java.biz
98 |

Class BasePage

99 |
100 |
101 |
    102 |
  • java.lang.Object
  • 103 |
  • 104 |
      105 |
    • macaca.java.biz.BasePage
    • 106 |
    107 |
  • 108 |
109 |
110 |
    111 |
  • 112 |
    113 |
    114 |
    public class BasePage
    115 | extends java.lang.Object
    116 |
    通用Page基类,用于页面的通用处理,比如页面返回以及其他
    117 |
  • 118 |
119 |
120 |
121 |
    122 |
  • 123 | 124 |
      125 |
    • 126 | 127 | 128 |

      Field Summary

      129 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 140 | 144 | 145 | 146 | 147 | 151 | 152 |
      Fields 
      Modifier and TypeField and Description
      BaseMacacaClient 139 | driver 142 |
      antClient driver
      143 |
      java.lang.StringpageDesc 149 |
      page desc 页面描述,日志输出时会用到,用于对当前页面一个可辨识的描述信息
      150 |
      153 |
    • 154 |
    155 | 156 |
      157 |
    • 158 | 159 | 160 |

      Constructor Summary

      161 | 163 | 164 | 165 | 166 | 167 | 168 | 172 | 173 | 174 | 180 | 181 |
      Constructors 
      Constructor and Description
      BasePage(java.lang.String pageDesc) 170 |
      构造函数 使用此方法只指定了页面描述,如果对页面进行操作,还需手动指定driver对象
      171 |
      BasePage(java.lang.String pageDesc, 176 | BaseMacacaClient driver) 178 |
      构造函数
      179 |
      182 |
    • 183 |
    184 | 185 |
      186 |
    • 187 | 188 | 189 |

      Method Summary

      190 | 192 | 198 | 199 | 200 | 201 | 202 | 203 | 206 | 209 | 210 | 211 | 212 | 218 | 219 | 220 | 221 | 226 | 227 |
      All Methods Instance Methods Concrete Methods 
      Modifier and TypeMethod and Description
      BaseMacacaClient 205 | getDriver()  208 |
      booleanhasPageShown(CommonUIBean bean) 216 |
      判断当前页面是否已经加载(判断方式为给出一个唯一标识的控件,通过判断该控件是否已经显示来确认页面是否已经加载)
      217 |
      voidsetDriver(BaseMacacaClient driver)  225 |
      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 |
      246 |
    • 247 | 248 | 249 |

      Field Detail

      250 | 251 | 252 | 253 |
        254 |
      • 255 |

        driver

        256 |
        public BaseMacacaClient driver
        258 |
        antClient driver
        259 |
      • 260 |
      261 | 262 | 263 | 264 |
        265 |
      • 266 |

        pageDesc

        267 |
        public java.lang.String pageDesc
        268 |
        page desc 页面描述,日志输出时会用到,用于对当前页面一个可辨识的描述信息
        269 |
      • 270 |
      271 |
    • 272 |
    273 | 274 |
      275 |
    • 276 | 277 | 278 |

      Constructor Detail

      279 | 280 | 281 | 282 |
        283 |
      • 284 |

        BasePage

        285 |
        public BasePage(java.lang.String pageDesc)
        286 |
        构造函数 使用此方法只指定了页面描述,如果对页面进行操作,还需手动指定driver对象
        287 |
        288 |
        Parameters:
        289 |
        pageDesc - 当前页面描述
        290 |
        291 |
      • 292 |
      293 | 294 | 295 | 296 |
        297 |
      • 298 |

        BasePage

        299 |
        public BasePage(java.lang.String pageDesc,
        300 |                 BaseMacacaClient driver)
        301 |
        构造函数
        302 |
        303 |
        Parameters:
        304 |
        pageDesc - 页面描述信息
        305 |
        driver - 在页面上的各种操作需要利用driver进行,需要将外部的driver指给当前Page
        306 |
        307 |
      • 308 |
      309 |
    • 310 |
    311 | 312 |
      313 |
    • 314 | 315 | 316 |

      Method Detail

      317 | 318 | 319 | 320 | 327 | 328 | 329 | 330 |
        331 |
      • 332 |

        setDriver

        333 |
        public void setDriver(BaseMacacaClient driver)
        336 |
      • 337 |
      338 | 339 | 340 | 341 |
        342 |
      • 343 |

        hasPageShown

        344 |
        public boolean hasPageShown(CommonUIBean bean)
        347 |
        判断当前页面是否已经加载(判断方式为给出一个唯一标识的控件,通过判断该控件是否已经显示来确认页面是否已经加载)
        348 |
        349 |
        Parameters:
        350 |
        bean - 用于唯一标识当前页面的控件
        351 |
        Returns:
        352 |
        true:已经显示, false:未显示
        353 |
        354 |
      • 355 |
      356 |
    • 357 |
    358 |
  • 359 |
360 |
361 |
362 | 363 | 364 |
365 | 366 | 367 | 368 | 369 | 370 | 371 | 379 |
380 | 425 | 426 | 427 | 428 | -------------------------------------------------------------------------------- /docs/macaca/java/biz/BasePageUI.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | BasePageUI 7 | 8 | 9 | 10 | 11 | 12 | 23 | 26 | 27 |
28 | 29 | 30 | 31 | 32 | 33 | 34 | 42 |
43 | 88 | 89 | 90 |
91 |
macaca.java.biz
92 |

Class BasePageUI

93 |
94 |
95 |
    96 |
  • java.lang.Object
  • 97 |
  • 98 |
      99 |
    • macaca.java.biz.BasePageUI
    • 100 |
    101 |
  • 102 |
103 |
104 |
    105 |
  • 106 |
    107 |
    108 |
    public class BasePageUI
    109 | extends java.lang.Object
    110 |
  • 111 |
112 |
113 |
114 |
    115 |
  • 116 | 117 |
      118 |
    • 119 | 120 | 121 |

      Constructor Summary

      122 | 124 | 125 | 126 | 127 | 128 | 129 | 132 | 133 |
      Constructors 
      Constructor and Description
      BasePageUI()  131 |
      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 |
182 | 183 | 184 | 185 | 186 | 187 | 188 | 196 |
197 | 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 |

macaca.java.biz

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 | 26 | 27 |
28 | 29 | 30 | 31 | 32 | 33 | 34 | 42 |
43 | 71 | 72 |
73 |

Package macaca.java.biz

74 |
75 |
76 |
    77 |
  • 78 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 89 | 92 | 93 | 94 | 96 | 99 | 100 | 101 | 103 | 106 | 107 | 108 | 110 | 111 | 112 | 113 | 115 | 116 | 117 | 118 | 120 | 121 | 122 | 123 | 125 | 126 | 127 | 128 |
    Class Summary 
    ClassDescription
    App 88 | 90 |
    Hello world!
    91 |
    BaseMacacaClient 97 |
    自定义的MacacaClient基类,用于在MacacaClient基础上封装自己的处理
    98 |
    BasePage 104 |
    通用Page基类,用于页面的通用处理,比如页面返回以及其他
    105 |
    BasePageUI 
    BaseUtils 
    CommonUIBean 
    ResultGenerator 
    129 |
  • 130 |
  • 131 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 142 | 143 | 144 | 145 | 147 | 148 | 149 | 150 | 152 | 153 | 154 | 155 |
    Enum Summary 
    EnumDescription
    BaseErrorType 
    BaseMacacaClient.GesturePinchType 
    BaseMacacaClient.PlatformType 
    156 |
  • 157 |
158 |
159 | 160 |
161 | 162 | 163 | 164 | 165 | 166 | 167 | 175 |
176 | 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 | 26 | 27 |
28 | 29 | 30 | 31 | 32 | 33 | 34 | 42 |
43 | 71 | 72 |
73 |

Hierarchy For Package macaca.java.biz

74 |
75 |
76 |

Class Hierarchy

77 | 108 |

Enum Hierarchy

109 | 131 |
132 | 133 |
134 | 135 | 136 | 137 | 138 | 139 | 140 | 148 |
149 | 177 | 178 | 179 | 180 | -------------------------------------------------------------------------------- /docs/overview-tree.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Class Hierarchy 7 | 8 | 9 | 10 | 11 | 12 | 23 | 26 | 27 |
28 | 29 | 30 | 31 | 32 | 33 | 34 | 42 |
43 | 71 | 72 |
73 |

Hierarchy For All Packages

74 | Package Hierarchies: 75 | 78 |
79 |
80 |

Class Hierarchy

81 | 112 |

Enum Hierarchy

113 | 134 |
135 | 136 |
137 | 138 | 139 | 140 | 141 | 142 | 143 | 151 |
152 | 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 | --------------------------------------------------------------------------------