{"id":21018722,"url":"https://github.com/tal-tech/wda-java-client","last_synced_at":"2025-05-15T06:31:44.430Z","repository":{"id":74709306,"uuid":"324123921","full_name":"tal-tech/wda-java-client","owner":"tal-tech","description":"Java Client for Appium WebDriverAgent, the api doc: https://documenter.getpostman.com/view/1837823/TVmMhJNB","archived":false,"fork":false,"pushed_at":"2021-03-04T06:51:29.000Z","size":47,"stargazers_count":18,"open_issues_count":0,"forks_count":3,"subscribers_count":13,"default_branch":"master","last_synced_at":"2025-04-03T05:12:22.878Z","etag":null,"topics":["appium-webdriveragent","wda-java-client","webdriveragent"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tal-tech.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-12-24T09:58:15.000Z","updated_at":"2024-06-28T09:30:59.000Z","dependencies_parsed_at":"2023-05-04T18:17:27.891Z","dependency_job_id":null,"html_url":"https://github.com/tal-tech/wda-java-client","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tal-tech%2Fwda-java-client","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tal-tech%2Fwda-java-client/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tal-tech%2Fwda-java-client/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tal-tech%2Fwda-java-client/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tal-tech","download_url":"https://codeload.github.com/tal-tech/wda-java-client/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254288251,"owners_count":22045866,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["appium-webdriveragent","wda-java-client","webdriveragent"],"created_at":"2024-11-19T10:27:23.793Z","updated_at":"2025-05-15T06:31:44.418Z","avatar_url":"https://github.com/tal-tech.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 开源WebDriverAgent的Java-client\n\nWebDriverAgent（wda）是iOS端一个最著名的UI自动化测试框架，Appium目前使用的xctest-driver也是基于WebDriverAgent来做二次封装和调用的，经常逛testerhome社区发现，其实很多公司也并没有直接用appium来做iOS自动化，而是直接调用WebDriverAgent来实现自己的iOS自动化框架。\n\n最近我也在做iOS的自动化框架，也是基于它来改造的，wda的代码写非常工整，方便阅读，是学习iOS自动化技术的典范，它内部的实现原理，其实比较简单，就是基于xctest，实现一个内部的http服务器，通过http api接口的形式提供外界调用，我用postman整理了一共71个接口，制作了一个文档：[WebDriverAgent Http Api 文档](https://documenter.getpostman.com/view/1837823/TVmMhJNB)，并基于这个api接口，开发了对应的java-client开源调用库，方便大家试用，也欢迎大家试用这个api接口完成Python的调用库，这将非常有价值！\n\n关于对WebDriverAgent的理解和使用，参见我这篇文章：[理解和使用WebDriverAgent](https://testerhome.com/articles/27059)\n\n### maven仓库地址\n\n```xml\ntodo：maven 仓库 \n```\n\n### 用法示例\n\n```java\nWDAClient client = new WDAClient(\"127.0.0.1\", 8100);\n// 检查wda是否健康\nclient.health();\nclient.getSessionApi().healthCheck();\n// 创建Session\nBaseResponse\u003cCreateSession\u003e res = client.getSessionApi().createSession();\nif (res.isSuccess) {\n  String sid = res.getValue().getSessionId();\n  // 启动应用\n\tBaseResponse r = this.client.getSessionApi().launchApp(sid, \"com.apple.Maps\");\n  assert r.isSuccess();\n}\n```\n\n### API列表\n\n假设新建了client对象：\n\n```java\nWDAClient client = new WDAClient(\"127.0.0.1\", 8100);\n```\n\n**全局Api**\n\n```java\n// 获取控件树\nString source = client.getPageSource();\n\n// 检查client是否健康\nboolean health = client.health();\n\n// 关闭wda client\nboolean bl = client.shutdown();\n```\n\n**Session会话Api**\n\n```java\n// 创建Session\nBaseResponse\u003cString\u003e res = client.getSessionApi().createSession();\n\n// 启动应用\nBaseResponse res = client.getSessionApi().launchApp(\"session id\", \"bundle id\");\n\n// 获取应用状态\nBaseResponse\u003cInteger\u003e res = client.getSessionApi().getAppState();\n\n// 激活应用（如果引用未启动，则重新启动）\nBaseResponse res = client.getSessionApi().activateApp(\"session id\", \"bundle id\");\n\n// 健康检查（wda会按一次home物理键，来检测手机是否卡主，wda是否正常工作）\nBaseResponse res = client.getSessionApi().healthCheck();\n```\n\n**Screenshot截图Api**\n\n```java\n// 截图（成功的话，返回Base64图片数据）\nBaseResponse\u003cString\u003e res = client.getScreenshotApi().screenshot();\n```\n\n**Orientation旋转Api**\n\n```java\n// 获取当前手机屏幕方向\n// 横向 - LANDSCAPE\n// 竖向 - PORTRAIT\nBaseResponse\u003cString\u003e res = client.getOrientationApi().getOrientation(\"session id\");\n```\n\n**Alert对话框Api**\n\n```java\n// 获取当前alet对话框的文本，如果失败那就是界面没有alert提示框\nBaseResponse\u003cString\u003e res = client.getAlertApi().getAlertText();\n\n// 获取alert对话框的操作按钮的文本列表\nBaseResponse\u003cList\u003cString\u003e\u003e res = client.getAlertApi().getAlertButtons(\"session id\");\n\n// 隐藏alert对话框\nBaseResponse res = client.getAlertApi().dismiss(\"session id\");\n\n// 点击对话框的某个按钮\nBaseResponse res = client.getAlertApi().accept(\"session id\", \"alert button name\");\n```\n\n**FindElement元素查找Api**\n\n```java \n// 查找符合某个条件的所有元素\nQueryInfo query = new QueryInfo();\nqueryInfo.setUsing(QueryUsing.CLASS_NAME);\nqueryInfo.setValue(\"XCUIElementTypeStaticText\");\nBaseResponse\u003cList\u003cElement\u003e\u003e res = client.getFindElementApi().elements(\"session id\", query);\n\n// 查找某个元素下的符合条件的所有子元素\nBaseResponse\u003cList\u003cElement\u003e\u003e res = client.getFindElementApi().elements(\"session id\", \"target element uuid\", query);\n```\n\n**Element元素Api**\n\n```java\n// 获取手机窗口大小\nBaseResponse\u003cWindowSize\u003e res = client.getElementApi().getWindowSize(\"session id\");\n\n// 检查某个元素是否禁用了\nBaseResponse\u003cBoolean\u003e res = client.getElementApi().enabled(\"session id\", \"element uuid\");\n\n// 获取某个元素的大小\nBaseResponse\u003cWDARect\u003e res = client.getElementApi().rect(\"session id\", \"element uuid\");\n\n// 获取某个元素的文本\nBaseResponse\u003cString\u003e res = client.getElementApi().text(\"session id\", \"element uuid\");\n\n// 检查某个元素是否展现了\nBaseResponse\u003cBoolean\u003e res = client.getElementApi().displayed(\"session id\", \"element uuid\");\n\n// 检查某个元素是否被选择了\nBaseResponse\u003cBoolean\u003e res = client.getElementApi().selected(\"session id\", \"element uuid\");\n\n// 获取某个元素的名称\nBaseResponse\u003cString\u003e res = client.getElementApi().name(\"session id\", \"element uuid\");\n\n// 对某个控件截图\nBaseResponse\u003cString\u003e res = client.getElementApi().screenshot(\"session id\", \"element uuid\");\n\n// 控件输入值\nBaseResponse res = client.getElementApi().value(\"session id\", \"element uuid\", \"value\");\n\n// 点击某个控件\nBaseResponse res = client.getElementApi().click(\"session id\", \"element uuid\");\n\n// 清空输入框\nBaseResponse res = client.getElementApi().clear(\"session id\", \"element uuid\");\n\n// 滑动某个控件\n// 将一个控件往某个方向滑动\n// 包含两个参数：\n// direction表示滚动方向，可选值有：up、down、left、right\n// velocity表示滚动速度，只建议从50-100，值越大速度越快\nString direction = \"down\";\nint velocity = 50;\nBaseResponse res = client.getElementApi().swip(\"session id\", \"element uuid\", direction, velocity);\n\n// 长按一个控件\n// 可以设置时长，时间单位为秒\nint duration = 3;\nBaseResponse res = client.getElementApi().touchAndHold(\"session id\", \"element uuid\", duration);\n\n// 坐标长按\n// 基于屏幕指定位置长按\n// x\t坐标x值\t100\tdouble\n// y\t坐标y值\t200\tdouble\n// duration\t长按时间，单位秒\t0.5\tdouble\nBaseResponse res = client.getElementApi().touchAndHoldInCoordinate(\"session id\", \"element uuid\", x, y, duration);\n\n// 控件拖动\nFromToParam param = new FromToParam();\nparam.setFromX(100);\nparam.setFromY(100);\nparam.setToX(500);\nparam.setToY(500);\nparam.setDuration(3);\nBaseResponse res = client.getElementApi().dragFromToForDuration(\"session id\", \"element uuid\", param);\n\n// 屏幕拖动(基于全屏幕的坐标拖动)\nBaseResponse res = client.getElementApi().dragFromToForDurationInCoordinate(\"session id\", param);\n\n// 拨动滚轮控件\n// 找到一个滚动，向上或向下滚动，滚动幅度取值从0.1到0.5，0.1表示一格，最大5格\n// 被选定的控件的类型必须为：XCUIElementTypePickerWheel，否则报错。\n// {\n//    \"order\": \"next\",  // 取值为next或者previous，不区分大小写\n//    \"offset\": 0.1 // 滚动幅度取值从0.1到0.5，0.1表示一格，最大5格\n// }\nBaseResponse res = client.getElementApi().pickWheel(\"session id\", \"uuid\", \"next or pre\", 1);\n\n// 输入文本\n// 对有输入焦点的控件输入字符串\n// 参数：\n// 字段名\t含义\t示例\n// value\t要输入的字符串数组\t[\"hello world\", \"dddd\"]\n// frequency\t输入速度，整形，数字越大速度越快\t10\n// 备注：\n// 如果当前界面没有输入焦点的控件，这个操作会等待一段时间直到超时或者有焦点的控件出现\nint frequency = 10;\nList\u003cString\u003e values = new ArrayList\u003c\u003e();\nvalues.add(\"hello world\");\nvalues.add(\"test\");\nBaseResponse res = client.getElementApi().keys(\"session id\", frequency, values);\n// 或者\nBaseResponse res = client.getElementApi().keys(\"session id\", frequency, ...keys);\n\n// 长按控件\n// 支持设定压力和时延，以及控件内的某个位置\n// pressure\t压力值\t0.5\n// duration\t按压的时间，单位秒\t3\n// x\t该控件内的某个点的x值\n// y\t该控件内的某个点的y值\nint x = 100;\nint y = 100;\nint duration = 2;\ndouble pressure = 0.5;\nBaseResponse res = client.getElementApi().forceTouch(\"session id\", \"element uuid\", x, y, duration, pressure);\n\n// 坐标双击\nBaseResponse res = client.getElementApi().doubleTap(\"session id\", x, y);\n```\n\n**Custom自定义Api**\n\n```java\n// 重启当前应用\nBaseResponse res = client.getCustomApi().deactiveApp(\"session id\");\n\n// 锁屏\nBaseResponse res = client.getCustomApi().lock();\n\n// 解锁\nBaseResponse res = client.getCustomApi().unlock();\n\n// 判断手机是否锁屏\nBaseResponse\u003cBoolean\u003e res = client.getCustomApi().locked();\n\n// 获取当前应用信息\nBaseResponse\u003cActiveAppInfo\u003e res = client.getCustomApi().getActiveAppInfo();\n\n// 获取当前设备信息\nBaseResponse\u003cWDADeviceInfo\u003e res = client.getCustomApi().getDeviceInfo();\n\n// 手机回到屏幕主页\nBaseResponse res = client.getCustomApi().homeScreen();\n```\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftal-tech%2Fwda-java-client","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftal-tech%2Fwda-java-client","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftal-tech%2Fwda-java-client/lists"}