{"id":13625344,"url":"https://github.com/openatx/facebook-wda","last_synced_at":"2025-04-23T20:58:29.401Z","repository":{"id":37359367,"uuid":"62980150","full_name":"openatx/facebook-wda","owner":"openatx","description":"Facebook WebDriverAgent Python Client Library (not official)","archived":false,"fork":false,"pushed_at":"2024-12-04T08:32:39.000Z","size":564,"stargazers_count":1789,"open_issues_count":67,"forks_count":277,"subscribers_count":57,"default_branch":"master","last_synced_at":"2025-04-23T20:58:22.390Z","etag":null,"topics":["python","wda","webdriveragent"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/openatx.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-07-10T03:39:16.000Z","updated_at":"2025-04-19T11:08:12.000Z","dependencies_parsed_at":"2022-08-03T04:16:13.440Z","dependency_job_id":"4644cbd3-a9ae-4861-a26f-dd990c41b2b3","html_url":"https://github.com/openatx/facebook-wda","commit_stats":{"total_commits":228,"total_committers":14,"mean_commits":"16.285714285714285","dds":"0.14912280701754388","last_synced_commit":"59bbb0e45528460276e8506643ebdab5f759d409"},"previous_names":[],"tags_count":95,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openatx%2Ffacebook-wda","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openatx%2Ffacebook-wda/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openatx%2Ffacebook-wda/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openatx%2Ffacebook-wda/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/openatx","download_url":"https://codeload.github.com/openatx/facebook-wda/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250514767,"owners_count":21443208,"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":["python","wda","webdriveragent"],"created_at":"2024-08-01T21:01:54.243Z","updated_at":"2025-04-23T20:58:29.383Z","avatar_url":"https://github.com/openatx.png","language":"Python","readme":"# python-wda\n[![Build Status](https://travis-ci.org/openatx/facebook-wda.svg?branch=master)](https://travis-ci.org/openatx/facebook-wda)\n[![PyPI](https://img.shields.io/pypi/v/facebook-wda.svg)](https://pypi.python.org/pypi/facebook-wda)\n[![PyPI](https://img.shields.io/pypi/l/facebook-wda.svg)]()\n\nFacebook WebDriverAgent Python Client Library (not official)\nImplemented apis describe in \u003chttps://github.com/facebook/WebDriverAgent/wiki/Queries\u003e\n\nMost functions finished.\n\nSince facebook/WebDriverAgent has been archived. Recommend use the forked WDA: https://github.com/appium/WebDriverAgent\n\nTested with: \u003chttps://github.com/appium/WebDriverAgent/tree/v2.16.1\u003e\n\n## Alternatives\n- gwda (Golang): https://github.com/ElectricBubble/gwda\n\n## Installation\n1. You need to start WebDriverAgent by yourself\n\n\t**New** There is a new tool, which can start WDA without xcodebuild, even you can run in Linux and Windows.\n\tSee: \u003chttps://github.com/alibaba/tidevice\u003e\n\n\tOr\n\n\tFollow the instructions in \u003chttps://github.com/appium/WebDriverAgent\u003e\n\n\tIt is better to start with Xcode to prevent CodeSign issues.\n\n\tBut it is also ok to start WDA with command line.\n\n\t```\n\txcodebuild -project WebDriverAgent.xcodeproj -scheme WebDriverAgentRunner -destination 'platform=iOS Simulator,name=iPhone 6' test\n\t```\n\n\tWDA在真机上运行需要一些配置，可以参考这篇文章 [ATX 文档 - iOS 真机如何安装 WebDriverAgent](https://testerhome.com/topics/7220)\n\n\t配置完之后运行下面的命令即可（需要用到Mac的密码，以及设备的UDID）\n\t\n\t```bash\n\t# 解锁keychain，以便可以正常的签名应用\n\tsecurity unlock-keychain -p $your-mac-password-here ~/Library/Keychains/login.keychain\n\n\t# 获取设备的UDID\n\tUDID=$(idevice_id -l | head -n1)\n\n\t# 运行测试\n\txcodebuild -project WebDriverAgent.xcodeproj -scheme WebDriverAgentRunner -destination \"id=$UDID\" test\n\t```\n\n2. Install python wda client\n\n\t```\n\tpip3 install -U facebook-wda\n\t```\n\n## TCP connection over USB (optional)\nYou can use wifi network, it is very convinient, but not very stable enough.\n\nI found a tools named `iproxy` which can forward device port to localhost, it\\'s source code is here \u003chttps://github.com/libimobiledevice/libusbmuxd\u003e\n\nThe usage is very simple `iproxy \u003clocal port\u003e \u003cremote port\u003e [udid]`\n\nFor more information see [SSH Over USB](https://iphonedevwiki.net/index.php/SSH_Over_USB)\n\n## Something you need to know\nfunction `window_size()` return UIKit size, While `screenshot()` image size is Native Resolution \n\n[![IOS Display](images/ios-display.png)](https://developer.apple.com/library/archive/documentation/DeviceInformation/Reference/iOSDeviceCompatibility/Displays/Displays.html)\n\nwhen use `screenshot`, the image size is pixels size. eg(`1080 x 1920`)\nBut this size is different with `c.window_size()`\n\nuse `session.scale` to get UIKit scale factor\n\n## Configuration\n```python\nimport wda\n\nwda.DEBUG = False # default False\nwda.HTTP_TIMEOUT = 60.0 # default 60.0 seconds\n```\n\n## How to use\n### Create a client\n\n```py\nimport wda\n\n# Enable debug will see http Request and Response\n# wda.DEBUG = True\nc = wda.Client('http://localhost:8100')\n\n# get env from $DEVICE_URL if no arguments pass to wda.Client\n# http://localhost:8100 is the default value if $DEVICE_URL is empty\nc = wda.Client()\n```\n\nA `wda.WDAError` will be raised if communite with WDA went wrong.\n\n**Experiment feature**: create through usbmuxd without `iproxy`\n\n\u003e Added in version: 0.9.0\n\nclass `USBClient` inherit from `Client`\n\nUSBClient connect to wda-server through `unix:/var/run/usbmuxd`\n\n```python\nimport wda\n\n# 如果只有一个设备也可以简写为\n# If there is only one iPhone connecttd\nc = wda.USBClient()\n\n# 支持指定设备的udid，和WDA的端口号\n# Specify udid and WDA port\nc = wda.USBClient(\"539c5fffb18f2be0bf7f771d68f7c327fb68d2d9\", port=8100)\n\n# 也支持通过DEVICE_URL访问\nc = wda.Client(\"usbmux://{udid}:8100\".format(udid=\"539c5fffb18f2be0bf7f771d68f7c327fb68d2d9\"))\nprint(c.window_size())\n\n# 注:\n# 仅在安装了tins的电脑上可以使用（目前并不对外开放)\n# 1.2.0 引入 wda_bundle_id 参数\nc = wda.USBClient(\"539c5fffb18f2be0bf7f771d68f7c327fb68d2d9\", port=8100, wda_bundle_id=\"com.facebook.custom.xctest\")\n```\n\n看到这里，可以看 [examples](examples) 目录下的一些代码了 \n\n### Client\n\n```py\n# Show status\nprint c.status()\n\n# Wait WDA ready\nc.wait_ready(timeout=300) # 等待300s，默认120s\nc.wait_ready(timeout=300, noprint=True) # 安静的等待，无进度输出\n\n# Press home button\nc.home()\n\n# Hit healthcheck\nc.healthcheck()\n\n# Get page source\nc.source() # format XML\nc.source(accessible=True) # default false, format JSON\n\nc.locked() # true of false\nc.lock() # lock screen\nc.unlock() # unlock\nc.app_current() # {\"pid\": 1281, \"bundleId\": \"com.netease.cloudmusic\"}\n\n# OpenURL not working very well\nc.open_url(\"taobao://m.taobao.com/index.htm\")\n```\n\nTake screenshot save as png\n\n```py\nc.screenshot('screen.png') # Good\nc.screenshot(\"screen.jpg\") # Bad\n\n# convert to PIL.Image and then save as jpg\nc.screenshot().save(\"screen.jpg\") # Good\n\nc.appium_settings() # 获取appium的配置\nc.appium_settings({\"mjpegServerFramerate\": 20}) # 修改配置\n```\n\n### Session\n\u003e From version 0.7.0, All Session methods moved to Client class. now Session is alias of Client\n\nOpen app\n\n```py\nwith c.session('com.apple.Health') as s:\n\tprint(s.orientation)\n```\n\nSame as\n\n```py\ns = c.session('com.apple.Health')\nprint(s.orientation)\ns.close()\n```\n\nFor web browser like Safari you can define page whit which will be opened:\n```python\ns = c.session('com.apple.mobilesafari', ['-u', 'https://www.google.com/ncr'])\nprint(s.orientation)\ns.close()\n```\n\nOther app operation (Works in [appium/WebDriverAgent](https://github.com/appium/WebDriverAgent))\n\n```bash\nc.app_current() # show current app info\n# Output example --\n# {'processArguments': {'env': {}, 'args': []},\n# 'name': '',\n# 'pid': 2978,\n# 'bundleId': 'com.apple.Preferences'}\n\n# Handle alert automatically in WDA (never tested before)\n# alert_action should be one of [\"accept\", \"dismiss\"]\ns = c.session(\"com.apple.Health\", alert_action=\"accept\")\n\n# launch without terminate app (WDAEmptyResponseError might raise)\nc.session().app_activate(\"com.apple.Health\") # same as app_launch\n\n# terminate app\nc.session().app_terminate(\"com.apple.Health\")\n\n# get app state\nc.session().app_state(\"com.apple.Health\")\n# output {\"value\": 4, \"sessionId\": \"xxxxxx\"}\n# different value means 1: die, 2: background, 4: running\n```\n\n### Session operations\n```python\n# set default element search timeout 30 seconds\ns.implicitly_wait(30.0)\n\n# Current bundleId and sessionId\nprint(s.bundle_id, s.id)\n\ns.home() # same as c.home(), use the same API\n\ns.lock() # lock screen\ns.unlock() # unlock screen\ns.locked() # locked status, true or false\n\ns.battery_info() # return like {\"level\": 1, \"state\": 2}\ns.device_info() # return like {\"currentLocale\": \"zh_CN\", \"timeZone\": \"Asia/Shanghai\"}\n\ns.set_clipboard(\"Hello world\") # update clipboard\n# s.get_clipboard() # Not working now\n\n# Screenshot return PIL.Image\n# Requires pillow, installed by \"pip install pillow\"\ns.screenshot().save(\"s.png\")\n\n# Sometimes screenshot rotation is wrong, but we can rotate it to the right direction\n# Refs: https://pillow.readthedocs.io/en/3.1.x/reference/Image.html#PIL.Image.Image.transpose\nfrom PIL import Image\ns.screenshot().transpose(Image.ROTATE_90).save(\"correct.png\")\n\n# One of \u003cPORTRAIT | LANDSCAPE\u003e\nprint(s.orientation) # expect PORTRAIT or LANDSCAPE\n\n# Change orientation\ns.orientation = wda.LANDSCAPE # there are many other directions\n\n# Deactivate App for some time\ns.deactivate(5.0) # 5s\n\n# Get width and height\nprint(s.window_size())\n# Expect tuple output (width, height)\n# For example: (414, 736)\n\n# Get UIKit scale factor, the first time will take about 1s, next time use cached value\nprint(s.scale)\n# Example output: 3\n\n# Simulate touch\ns.tap(200, 200)\n\n# Very like tap, but support float and int argument\n# float indicate percent. eg 0.5 means 50%\ns.click(200, 200)\ns.click(0.5, 0.5) # click center of screen\ns.click(0.5, 200) # click center of x, and y(200)\n\n# Double touch\ns.double_tap(200, 200)\n\n# Simulate swipe, utilizing drag api\ns.swipe(x1, y1, x2, y2, 0.5) # 0.5s\ns.swipe(0.5, 0.5, 0.5, 1.0)  # swipe middle to bottom\n\ns.swipe_left()\ns.swipe_right()\ns.swipe_up()\ns.swipe_down()\n\n# tap hold for 1 seconds\ns.tap_hold(x, y, 1.0)\n\n# Hide keyboard (not working in simulator), did not success using latest WDA\n# s.keyboard_dismiss()\n\n# press home, volumeUp, volumeDown\ns.press(\"home\") # fater then s.home()\ns.press(\"volumeUp\")\ns.press(\"volumeDown\")\n\n# New in WebDriverAgent(3.8.0)\n# long press home, volumeUp, volumeDown, power, snapshot(power+home)\ns.press_duration(\"volumeUp\", 1) # long press for 1 second\ns.press_duration(\"snapshot\", 0.1)\n```\n\n### Find element\n\u003e Note: if element not found, `WDAElementNotFoundError` will be raised\n\n```python\n# For example, expect: True or False\n# using id to find element and check if exists\ns(id=\"URL\").exists # return True or False\n\n# using id or other query conditions\ns(id='URL')\n\n# using className\ns(className=\"Button\")\n\n# using name\ns(name='URL')\ns(nameContains='UR')\ns(nameMatches=\".RL\")\n\n# using label\ns(label=\"label\")\ns(labelContains=\"URL\")\n\n# using value\ns(value=\"Enter\")\ns(valueContains=\"RL\")\n\n# using  visible, enabled\ns(visible=True, enabled=True)\n\n# using index, index must combined with at least on label,value, etc...\ns(name='URL', index=1) # find the second element. index of founded elements, min is 0\n\n# combines search conditions\n# attributes bellow can combines\n# :\"className\", \"name\", \"label\", \"visible\", \"enabled\"\ns(className='Button', name='URL', visible=True, labelContains=\"Addr\")\n```\n\nMore powerful finding method\n\n```python\ns(xpath='//Button[@name=\"URL\"]')\n\n# another code style\ns.xpath('//Button[@name=\"URL\"]')\n\ns(predicate='name LIKE \"UR*\"')\ns('name LIKE \"U*L\"') # predicate is the first argument, without predicate= is ok\ns(classChain='**/Button[`name == \"URL\"`]')\n```\n\nTo see more `Class Chain Queries` examples, view \u003chttps://github.com/facebookarchive/WebDriverAgent/wiki/Class-Chain-Queries-Construction-Rules\u003e\n\n[Predicate Format String Syntax](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Predicates/Articles/pSyntax.html)\n\n### Get Element info\n```python\n# if not found, raise WDAElementNotFoundError\ne = s(text='Dashboard').get(timeout=10.0)\n\n# e could be None if not exists\ne = s(text='Dashboard').wait(timeout=10.0)\n\n# get element attributes\ne.className # XCUIElementTypeStaticText\ne.name # XCUIElementTypeStaticText  /name\ne.visible # True    /attribute/visible\ne.value # Dashboard /attribute/value\ne.label # Dashboard /attribute/label\ne.text # Dashboard  /text\ne.enabled # True    /enabled\ne.displayed # True  /displayed\n\ne.bounds # Rect(x=161, y=32, width=53, height=21)  /rect\nx, y, w, h = e.bounds\n\n\n```\n\n### Element operations (eg: `tap`, `scroll`, `set_text` etc...)\nExmaple search element and tap\n\n```python\n# Get first match Element object\n# The function get() is very important.\n# when elements founded in 10 seconds(:default:), Element object returns\n# or WDAElementNotFoundError raises\ne = s(text='Dashboard').get(timeout=10.0)\n# s(text='Dashboard') is Selector\n# e is Element object\ne.tap() # tap element\n```\n\n\u003eSome times, I just hate to type `.get()`\n\nUsing python magic tricks to do it again.\n\n```python\n# \tusing python magic function \"__getattr__\", it is ok with out type \"get()\"\ns(text='Dashboard').tap()\n# same as\ns(text='Dashboard').get().tap()\n```\n\nNote: Python magic tricks can not used on get attributes\n\n```python\n# Accessing attrbutes, you have to use get()\ns(text='Dashboard').get().value\n\n# Not right\n# s(text='Dashboard').value # Bad, always return None\n```\n\nClick element if exists\n\n```python\ns(text='Dashboard').click_exists() # return immediately if not found\ns(text='Dashboard').click_exists(timeout=5.0) # wait for 5s\n```\n\nOther Element operations\n\n```python\n# Check if elements exists\nprint(s(text=\"Dashboard\").exists)\n\n# Find all matches elements, return Array of Element object\ns(text='Dashboard').find_elements()\n\n# Use index to find second element\ns(text='Dashboard')[1].exists\n\n# Use child to search sub elements\ns(text='Dashboard').child(className='Cell').exists\n\n# Default timeout is 10 seconds\n# But you can change by\ns.set_timeout(10.0)\n\n# do element operations\ne.tap()\ne.click() # alias of tap\ne.clear_text()\ne.set_text(\"Hello world\")\ne.tap_hold(2.0) # tapAndHold for 2.0s\n\ne.scroll() # scroll to make element visiable\n\n# directions can be \"up\", \"down\", \"left\", \"right\"\n# swipe distance default to its height or width according to the direction\ne.scroll('up')\n\n# Set text\ne.set_text(\"Hello WDA\") # normal usage\ne.set_text(\"Hello WDA\\n\") # send text with enter\ne.set_text(\"\\b\\b\\b\") # delete 3 chars\n\n# Wait element gone\ns(text='Dashboard').wait_gone(timeout=10.0)\n\n# Swipe\ns(className=\"Image\").swipe(\"left\")\n\n# Pinch\ns(className=\"Map\").pinch(2, 1) # scale=2, speed=1\ns(className=\"Map\").pinch(0.1, -1) # scale=0.1, speed=-1 (I donot very understand too)\n\n# properties (bool)\ne.accessible\ne.displayed\ne.enabled\n\n# properties (str)\ne.text # ex: Dashboard\ne.className # ex: XCUIElementTypeStaticText\ne.value # ex: github.com\n\n# Bounds return namedtuple\nrect = e.bounds # ex: Rect(x=144, y=28, width=88.0, height=27.0)\nrect.x # expect 144\n```\n\nAlert\n\n```python\nprint(s.alert.exists)\nprint(s.alert.text)\ns.alert.accept() # Actually do click first alert button\ns.alert.dismiss() # Actually do click second alert button\ns.alert.wait(5) # if alert apper in 5 second it will return True,else return False (default 20.0)\ns.alert.wait() # wait alert apper in 2 second\n\ns.alert.buttons()\n# example return: [\"设置\", \"好\"]\n\ns.alert.click(\"设置\")\ns.alert.click([\"设置\", \"信任\", \"安装\"]) # when Arg type is list, click the first match, raise ValueError if no match\n```\n\nAlert monitor\n\n```python\nwith c.alert.watch_and_click(['好', '确定']):\n\ts(label=\"Settings\").click() # \n\t# ... other operations\n\n# default watch buttons are\n# [\"使用App时允许\", \"好\", \"稍后\", \"稍后提醒\", \"确定\", \"允许\", \"以后\"]\nwith c.alert.watch_and_click(interval=2.0): # default check every 2.0s\n\t# ... operations\n```\n\n### Callback\n回调操作: `register_callback`\n\n```python\nc = wda.Client()\n\n# 使用Example\ndef device_offline_callback(client, err):\n\tif isinstance(err, wda.WDABadGateway):\n\t\tprint(\"Handle device offline\")\n\t\tok = client.wait_ready(60) # 等待60s恢复\n\t\tif not ok:\n\t\t\treturn wda.Callback.RET_ABORT\n\t\treturn wda.Callback.RET_RETRY\n\nc.register_callback(wda.Callback.ERROR, device_offline_callback, try_first=True)\n# try_first 优先使用device_offline_callback函数处理ERROR\n\n\n# the argument name in callback function can be one of\n# - client: wda.Client\n# - url: str, eg: http://localhost:8100/session/024A4577-2105-4E0C-9623-D683CDF9707E/wda/keys\n# - urlpath: str, eg: /wda/keys  (without session id)\n# - with_session: bool # if url contains session id\n# - method: str, eg: GET\n# - response: dict # Callback.HTTP_REQUEST_AFTER only \n# - err: WDAError # Callback.ERROR only\n#\ndef _cb(client: wda.Client, url: str):\n\tif url.endswith(\"/wda/keys\"):\n\t\tprint(\"send_keys called\")\n\nc.register_callback(wda.Callback.HTTP_REQUEST_BEFORE, _cb)\nc.register_callback(wda.Callback.HTTP_REQUEST_BEFORE, lambda url: print(url), try_first=True) # 回调会比_cb更先回调\nc.send_keys(\"Hello\")\n\n# unregister\nc.unregister_callback(wda.Callback.HTTP_REQUEST_BEFORE, _cb)\nc.unregister_callback(wda.Callback.HTTP_REQUEST_BEFORE) # ungister all\nc.unregister_callback() # unregister all callbacks\n```\n\n支持的回调有\n\n```\nwda.Callback.HTTP_REQUEST_BEFORE\nwda.Callback.HTTP_REQUEST_AFTER\nwda.Callback.ERROR\n```\n\n默认代码内置了两个回调函数 `wda.Callback.ERROR`，使用`c.unregister_callback(wda.Callback.ERROR)`可以去掉这两个回调\n\n- 当遇到`invalid session id`错误时，更新session id并重试\n- 当遇到设备掉线时，等待`wda.DEVICE_WAIT_TIMEOUT`时间 (当前是30s，以后可能会改的更长一些)\n\n## TODO\nlongTap not done pinch(not found in WDA)\n\nTouchID\n\n* Match Touch ID\n* Do not match Touch ID\n\n## How to handle alert message automaticly (need more tests)\nFor example\n\n```python\nimport wda\n\ns = wda.Client().session()\n\ndef _alert_callback(session):\n    session.alert.accept()\n\ns.set_alert_callback(_alert_callback) # deprecated，此方法不能用了\n\n# do operations, when alert popup, it will auto accept\ns(type=\"Button\").click()\n```\t\n\n## Special property\n```python\n# s: wda.Session\ns.alibaba.xxx # only used in alibaba-company\n```\n\n## DEVELOP\nSee [DEVELOP.md](DEVELOP.md) for more details.\n\n## iOS Build-in Apps\n**苹果自带应用**\n\n|   Name | Bundle ID          |\n|--------|--------------------|\n| iMovie | com.apple.iMovie |\n| Apple Store | com.apple.AppStore |\n| Weather | com.apple.weather |\n| 相机Camera | com.apple.camera |\n| iBooks | com.apple.iBooks |\n| Health | com.apple.Health |\n| Settings | com.apple.Preferences |\n| Watch | com.apple.Bridge |\n| Maps | com.apple.Maps |\n| Game Center | com.apple.gamecenter |\n| Wallet | com.apple.Passbook |\n| 电话 | com.apple.mobilephone |\n| 备忘录 | com.apple.mobilenotes |\n| 指南针 | com.apple.compass |\n| 浏览器 | com.apple.mobilesafari |\n| 日历 | com.apple.mobilecal |\n| 信息 | com.apple.MobileSMS |\n| 时钟 | com.apple.mobiletimer |\n| 照片 | com.apple.mobileslideshow |\n| 提醒事项 | com.apple.reminders |\n| Desktop | com.apple.springboard (Start this will cause your iPhone reboot) |\n\n**第三方应用 Thirdparty**\n\n|   Name | Bundle ID          |\n|--------|--------------------|\n| 腾讯QQ | com.tencent.mqq |\n| 微信 | com.tencent.xin |\n| 部落冲突 | com.supercell.magic |\n| 钉钉 | com.laiwang.DingTalk |\n| Skype | com.skype.tomskype |\n| Chrome | com.google.chrome.ios |\n\n\nAnother way to list apps installed on you phone is use `ideviceinstaller`\ninstall with `brew install ideviceinstaller`\n\nList apps with command\n\n```sh\n$ ideviceinstaller -l\n```\n\n## Tests\n测试的用例放在`tests/`目录下，使用iphone SE作为测试机型，系统语言应用。调度框架`pytest`\n\n## WDA Benchmark E2E Tests\n[E2E Tests](e2e_benchmarks)\nLatest WDA Version Testing Report:\n- [WDA Version 7.1.1](e2e_benchmarks/reports/WDA_V711.md)\n- [WDA Version 6.1.1](e2e_benchmarks/reports/WDA_V611.md)\n\n## Reference\nSource code\n\n- [Router](https://github.com/facebook/WebDriverAgent/blob/master/WebDriverAgentLib/Commands/FBElementCommands.m#L62)\n- [Alert](https://github.com/facebook/WebDriverAgent/blob/master/WebDriverAgentLib/Commands/FBAlertViewCommands.m#L25)\n\n## Thanks\n- https://github.com/msabramo/requests-unixsocket\n- https://github.com/iOSForensics/pymobiledevice\n\n## Articles\n* \u003chttps://testerhome.com/topics/5524\u003e By [diaojunxiam](https://github.com/diaojunxian)\n\n## Contributors\n* [diaojunxian](https://github.com/diaojunxian)\n* [iquicktest](https://github.com/iquicktest)\n\n## DESIGN\n[DESIGN](DESIGN.md)\n\n## LICENSE\n[MIT](LICENSE)\n\n","funding_links":[],"categories":["Python"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenatx%2Ffacebook-wda","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopenatx%2Ffacebook-wda","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenatx%2Ffacebook-wda/lists"}