appium-for-mac, 使用JSON协议实现mac应用自动化的应用

分享于 

16分钟阅读

GitHub

  繁體 雙語
Proof of concept for automating a mac app with JSON wire protocol
  • 源代码名称:appium-for-mac
  • 源代码网址:http://www.github.com/appium/appium-for-mac
  • appium-for-mac源代码文档
  • appium-for-mac源代码下载
  • Git URL:
    git://www.github.com/appium/appium-for-mac.git
    Git Clone代码到本地:
    git clone http://www.github.com/appium/appium-for-mac
    Subversion代码到本地:
    $ svn co --depth empty http://www.github.com/appium/appium-for-mac
    Checked out revision 1.
    $ cd repo
    $ svn up trunk
    
    用于Mac的 Appium

    Mac的Appium可以使用 selenium/WebDriver 和 OS X 辅助API控制Mac应用程序的本地用户界面。 查看将控制计算器应用程序的示例。

    WebDriver服务器位于端口 4622上。 如果你自己构建它,你可以在 AppiumForMacAppDelegate.m. 中更改这个值

    要求

    • 运行:Mac OS X 10.7或者更高版本。
    • 构建:Xcode 7.2.1或者更高版本。

    安装

    Mac OS X 不允许应用程序在未经许可的情况下使用 Accessibility API,因此你必须手动启用它。

    10.7

    • 打开系统首选项> 通用访问。
    • 选中"启用辅助设备访问"复选框。

    10.8

    • 打开系统首选项> 辅助功能。
    • 选中"启用辅助设备访问"复选框。

    10.9,10.10,10.11,

    • 打开系统偏好设置> 安全&隐私。
    • 单击隐私选项卡。
    • 在左侧表格中单击辅助功能。
    • 如果需要,请单击锁定以进行更改。
    • 如果在应用程序列表中没有看到 AppiumForMac.app,则将它的拖到Finder中的列表中。
    • 检查 AppiumForMac.app. 旁边的复选标记

    Scripters的新特性( 如 2017年04月 )

    你可以在 calculator.py 示例脚本中看到新特性。

    本机事件

    AppiumForMac将使用动作语法生成 OS X 本机键盘和鼠标事件。 在/examples/calculator.py. 中有几个例子

    单击

    ActionChains(driver). 单击( 元素) ( )

    ActionChains(driver). 单击( ) ( )

    移动到

    ActionChains(driver). move_to_element ( 元素) ( )

    电子邮件发送密钥

    ActionChains(driver). send_keys ('一个要键入的字符串')。perform ( )

    绝对 AXPath

    虽然这需要从脚本中进行协作,但这是一个巨大的性能改进。 不要使用部分 XPath,而是使用简单的绝对 AXPath。 这是基于 OS X 辅助功能结构,你可以在辅助功能检查器中查看。 因为只支持XPath语法的有限子集,所以路径是"简单"。 使用绝对AXPaths时,使用XPath定位对象是高度优化的。

    简单的绝对 AXPath:

    
    * is a string with valid XPath syntax
    
    
    * uses OS X Accessibility constants, e.g. AXMenuItem or AXTitle
    
    
    * can specify any accessible element on the screen, in any application or window, any time
    
    
    * begins with/AXApplication, and contains at least one other node
    
    
    * does not contain"//", or use a wildcard, or specify multiple paths using |
    
    
    * uses predicates with a single integer for an index, or, one or more string comparisons using = and!=
    
    
    * may use boolean operators"and" or"or" (mutually exclusive) in between multiple comparisons
    
    
    * there must be a leading and trailing space, e.g." and"
    
    
    * does not use predicate strings containing braces [] or parens ()
    
    
    * uses single quotes, not double quotes for attribute strings
    
    
    * does not contain spaces, except within attribute string values (optional), and, surrounding boolean operators (required)
    
    
    
    

    注释:

    
    * The node"/AXApplication" without a predicate denotes the frontmost application.
    
    
    * Attribute values nil and '' (empty string) are defined to be equivalent.
    
    
    * For example, if a menu item does not have a mark character (i.e. the value is nil) then @AXMenuItemMarkChar=='' is true.
    
    
    * Index predicates are valid for nodes with the same AXRole. For example, AXGroup[0] refers to the first AXGroup, not simply the first child element.
    
    
    
    

    很好的例子:

    
    "/AXApplication[@AXTitle='Calculator']/AXWindow[0]/AXGroup[1]/AXButton[@AXDescription='clear']"
    
    
    
    "/AXApplication[@AXTitle='Calculator']/AXMenuBarItems/AXMenuBarItem[@AXTitle='View']/AXMenu/AXMenuItem[@AXTitle='Scientific']"
    
    
    
    "/AXApplication/AXMenuBarItems/AXMenuBarItem[@AXTitle='View']/AXMenu/AXMenuItem[@AXTitle='Basic' and @AXMenuItemMarkChar!='']"
    
    
    
    

    错误的例子:

    
    "//AXButton[@AXDescription='clear']"
    
    
    (does not begin with/AXApplication, and contains//)
    
    
    
    "/AXApplication[@AXTitle='Calculator']/AXWindow[0]/AXButton[@AXDescription='clear']"
    
    
    (not an absolute path: missing AXGroup)
    
    
    
    "/AXApplication[@AXTitle="Calculator"]/AXWindow[0]"
    
    
    (a predicate string uses double quotes)
    
    
    
    "/AXApplication[@AXTitle='Calculator']"
    
    
    (path does not contain at least two nodes)
    
    
    
    "/AXApplication[@AXTitle='Calculator']/AXMenuBar/AXMenuBarItems/AXMenuBarItem[@AXTitle='(Window)']"
    
    
    (a predicate string contains forbidden characters)
    
    
    
    "/AXApplication[@AXTitle='Calculator']/AXWindow[0]/AXGroup[1]/AXButton[@AXDescription ='clear']"
    
    
    (a predicate contain a space before the =)
    
    
    
    "/AXApplication[@AXTitle='Calculator']/AXWindow[position()>3]/AXGroup[1]/AXButton[@AXDescription='clear']"
    
    
    (a predicate is not a simple string or integer, and specifies more than one node)
    
    
    
    "/AXApplication/AXMenuBarItems/AXMenuBarItem[@AXTitle='View']/AXMenu/AXMenuItem[@AXTitle='Basic' and@AXMenuItemMarkChar!='']"
    
    
    (leading and trailing spaces required for the boolean operator)
    
    
    
    "/AXApplication[@AXTitle="Calculator"]/AXWindow[0]/AXButton[@AXDescription='clear' and @AXEnabled='YES' or @AXDescription='clear all']"
    
    
    (predicate uses multiple kinds of boolean operators; use one or more 'and', or, use one or more 'or', but not both)
    
    
    
    

    自动AXPath记录

    为元素生成AXPath很简单: 运行AppiumForMac时,只需使用鼠标指向某个元素,然后按下 fn ( 函数) 键几秒钟。 AppiumForMac将在屏幕上构建元素的AXPath,并将它的复制到剪贴板。 然后你可以将它粘贴到你的脚本中。

    会话终止 switch

    如果你的脚本已经关闭 Rails,你需要停止它。 但是,如果脚本运行,它可以继续键入并在你试图取消它时单击。 现在,会话进行中,你可以按下( 函数) 键几秒钟。 AppiumForMac将取消所有打开的会话。 你的脚本将收到"没有这样的会话"错误。

    新会话属性

    AppiumForMac会话有几个新属性。 请参见下面的描述。 你可以在会话进行期间读取和写入属性值,使用 Cookies ! 是的使用 Cookies 是一种奇怪的方式,但这是我可以考虑支持获取和设置通用会话属性的唯一方法。 在 selenium 中有两个现有命令,但这些命令仅限于一小组属性,例如超时。

    使用Cookie获取和设置属性

    每个cookie都是一个至少有两个键的字典: ''还有'值。selenium 命令为: get_cookies,get_cookie ( ) 和 addCookie()。

    • 要获取所有 Cookies,请使用 driver.get_cookies()。 这将返回一个 array 字典的。
    • 要获得一个 cookie,请使用 driver.get_cookie('cookieName')。 这将返回带有 NAME'cookiename'的cookie。
    • 要设置 cookie,请使用驱动程序。add_cookie ( {'名称': 'cookiename','值':'cookievalue'} )。
    • 隐式超时

    在查找元素时,AppiumForMac支持标准隐式超时。 默认值为 0.0秒,也就是说,只有一次尝试。

    
    For example, to set a 20.5 second timeout, use driver.add_cookie({'name': 'implicit_timeout', 'value': 20.5}). 
    
    
    
    
    循环延迟

    在要查找元素的隐式超时期间,可以指定在两次尝试之间等待的时间。 默认值为 1.0秒。 在每次尝试后,循环延迟会发生,所以如果在第一次尝试时发现了元素,则不会延迟。 无论loop_delay值如何,等待时间都不会超过 implicit_timeout。

    
    For example, to set a 1.7 second loop delay, use driver.add_cookie({'name': 'loop_delay', 'value': 1.7}). 
    
    
    
    
    命令延迟

    这提供了一个简单的方法来在需要时减慢脚本,比如 用于调试。 它指定了一个任意延迟的延迟,在每个命令之前。 默认为 0.0秒,因此你的脚本以全速运行 !

    
    For example, to wait 2.5 seconds before executing each command, use driver.add_cookie({'name': 'command_delay', 'value': 2.5}).
    
    
    
    
    鼠标速度

    对于本机鼠标事件,这决定鼠标在屏幕上移动的速度,大约是每秒的点数。 默认值为 100.50的值将移动鼠标的速度比 100快一半。

    
    For example, to set a very slow speed, use driver.add_cookie({'name': 'mouse_speed', 'value': 5}).
    
    
    
    

    小心设置鼠标速度太高,或者你的应用程序可能无法检测到某些元素的鼠标。

    会话诊断目录

    AppiumForMac可以为所有诊断创建一个全局目录,名为"appiumdiagnostics"。 这将包含其他项目,如每个会话诊断目录。 每个会话目录存储诸如屏幕快照之类的项目。 为全局目录设置字符串文件路径。 默认情况下不使用诊断目录。 如果不设置路径,或者为路径设置空字符串,则不会有诊断记录,例如屏幕截图。

    
    For example, driver.add_cookie({'name': 'global_diagnostics_directory', 'value': '~/Desktop'}).
    
    
    
    
    屏幕快照错误

    在隐式超时之前没有找到元素时,AppiumForMac可以自动获取屏幕快照。 这些可以用于分析错误。 屏幕快照存储在每个会话诊断目录中。 默认情况下,不为错误创建屏幕快照。 如果你不设置 global_diagnostics_directory cookie,即使你启用了它们,也没有屏幕快照。

    
    For example, to enable the feature, use driver.add_cookie({'name': 'screen_shot_on_error', 'value': True}).
    
    
    
    For example, to enable the feature, use driver.add_cookie({'name': 'screen_shot_on_error', 'value': False}).
    
    
    
    

    开发人员的新特性( 如 2017年04月 )

    极大简化了命令处理程序的代码 Pattern。

    处理程序方法的代码 Pattern 已经基本更改。 AfMSessionController: executewebdrivercommandwithpath: onmainthread: commandblock:,执行基于路径,提取json参数,验证元素和延迟时间和延迟的新方法。 处理程序变成一个简单的代码块,只包含该处理程序的唯一函数代码。

    每个处理程序的NAME 是从http请求动态构造的。 你所要做的就是正确的NAME 处理器,它会被执行。

    创建一个新的命令处理程序
    • 转到 AfMHandlers.m.
    • 查找现有的处理程序方法。 你可能希望找到与要添加的新命令类似的一个。
    • 将处理程序方法复制到剪贴板。
    • 在新的处理程序方法中找到注释掉的存根并粘贴到该位置。
    • 重命名新的处理程序,按照其他处理程序的命名 Pattern 命名。
    • 用新的处理程序代码替换处理程序块。
    • 更新头文件( afmhandlers.h ) 以便其他人可以轻松地看到哪些命令是。
    • 更新 onMainThread: executeWebDriverCommandWithPath的参数: 通常,命令不必在主线程上执行,因此不要使用。
    • 你的新命令处理程序的运行时

    每当AppiumForMac收到它的匹配的有线协议请求时,就会自动调用。

    你的处理程序代码块接收三个参数: 会话,commandParams和状态。

    • 会话:创建新的网络驱动程序时创建的AfMSessionController实例。 这提供了对机器和其他应用程序的访问。
    • commandParams: 包含http请求参数的字典。 它包括从URL路径引用的元素,以及所有的POST json对象。 "elementobject"字典键检索经过验证的元素。
    • 状态:指向int的指针,将状态代码写回调用方。 这不是你的处理程序返回值的替代。

    代码块应返回由 [AppiumMacHTTPJSONResponse responseWithJson:status:session:] 或者 [AppiumMacHTTPJSONResponse responseWithJsonError:session:] 创建的对象和状态值。

    如果代码块返回 responsewithjsonerror: kafmstatuscodenosuchelement,则块( 不是整个处理程序方法) 将在implicitTimeout的约束和loopDelay内再次调用。

    但是,如果块返回零,那么就会立即返回一个kAfMStatusCodeNoSuchElement错误,立即返回脚本脚本,即使implicitTimeout还未到达脚本。

    如果要处理抛出的异常,请在自己的代码块中放置一个try块。 未捕获的执行异常被记录,但不会被丢弃。

    AppiumForMac自动将常见错误返回给脚本,这样你就不必担心它们:

    • kAfMStatusCodeNoSuchDriver - 在请求路径中没有指定的sessionId会话
    • kAfMStatusCodeUnknownCommand - 你的处理程序方法可能被命名错误
    • kAfMStatusCodeStaleElementReference - 以前定位的元素不再存在
    • kAfMStatusCodeNoSuchWindow - 当前窗口不再存在
    • kAfMStatusCodeSessionNotCreatedException - 会话的最大数量是打开

    AUTO  mac  proto  protocol  protoc  
    相关文章