Appium 与 WebDriver
运行 droidline webdriver,并把 Appium 客户端指向它。用 Python、Java、JavaScript 等语言写的现有 Appium 脚本可以不经 ADB,通过 Droidline 控制手机。
本页为译文。如与英文版不一致,以英文版为准。 English
droidline webdriver 支持 W3C WebDriver 协议以及 Appium 的 Android 扩展。把 Appium 客户端指向它,为 Appium 编写的脚本就会通过 Droidline 控制手机:定位方式和元素命令相同,不需要 ADB,也不需要 Appium 服务器。
这是可选功能,只在命令运行期间工作。你的 Droidline 脚本不需要它。
启动
Droidline 服务器需要正在运行。在另一个终端中运行:
droidline webdriver
WebDriver bridge on http://127.0.0.1:4723
Use it as the Appium server URL. Stop with Ctrl+C.
客户端要求填写 Appium 服务器地址时,使用 http://127.0.0.1:4723。--listen 用来选择其他地址;请保持为 127.0.0.1,因为桥接没有密码。
连接
# pip install Appium-Python-Client
from appium import webdriver
from appium.options.android import UiAutomator2Options
from appium.webdriver.common.appiumby import AppiumBy
opts = UiAutomator2Options()
opts.set_capability("appium:udid", "shelf-01")
opts.set_capability("appium:appPackage", "com.android.settings")
d = webdriver.Remote("http://127.0.0.1:4723", options=opts)
d.find_element(AppiumBy.XPATH, "//*[@text='网络和互联网']").click()
d.find_element(AppiumBy.ANDROID_UIAUTOMATOR, 'new UiSelector().text("WLAN")')
d.quit()import { remote } from "webdriverio";
const d = await remote({
hostname: "127.0.0.1",
port: 4723,
capabilities: { platformName: "Android", "appium:udid": "shelf-01" },
});
await d.$("~更多选项").click();
await d.deleteSession();上面的 Appium Python 客户端已经在真机上通过这个桥接测试过。WebdriverIO、Java 和 .NET 客户端、Robot Framework 的 AppiumLibrary、Appium Inspector 等使用同一协议的其他客户端也以相同方式连接。客户端发送桥接不支持的命令时,它会回复 unknown command 并给出命令名称。
Capability
| Capability | 作用 |
|---|---|
platformName | Android,或者省略。 |
appium:udid 或 droidline:device | 手机的 ID 或名称。不指定时使用唯一在线的手机。 |
appium:deviceName | 只有当某部已配对手机正好是这个名称或 ID 时才使用,其他值都会被忽略。 |
appium:appPackage、appium:appActivity | 启动这个应用。不会重置,也不会清除数据;mobile: clearApp 只在设备所有者模式下清除应用数据。 |
appium:newCommandTimeout | 这么多秒内没有命令就结束会话。默认 60,0 表示永不结束。 |
droidline:lease | true 会在会话期间租用一部空闲手机,会话结束时归还。 |
定位方式
| 方式 | 匹配 |
|---|---|
xpath | 在页面源码上执行 XPath,标签和属性与 UiAutomator2 相同(@text、@resource-id、@content-desc、@class、@bounds 以及各状态值)。 |
id | resource-id,完整的或只写 :id/ 之后的名称。 |
accessibility id | content-desc。 |
class name | 类名,例如 android.widget.Button。 |
-android uiautomator | new UiSelector() 的 text、textContains、textStartsWith、textMatches、description 及其变体、resourceId、className、packageName、各状态值、instance、childSelector 和 fromParent,以及 new UiScrollable(...).scrollIntoView(...) 和 scrollTextIntoView(...)。 |
-droidline query | 以 JSON 书写的 Droidline 查询,例如 {"class":"android.widget.Switch","row":{"text":"WLAN"}}。 |
name | text。 |
用 implicitly_wait 设置的隐式等待适用于所有方式;与 WebDriver 一样,设置之前为 0。
支持的功能
- 元素:查找一个或多个,也可以在另一个元素内部查找;
click、send_keys、clear、text、get_attribute、rect、is_displayed、is_enabled、is_selected以及元素截图。已经离开屏幕的元素会引发 stale element 错误。 - 页面源码、截图和窗口尺寸。
- 单指 W3C actions:点击、长按和滑动。key actions 可以输入文字,并按下 Enter、Backspace 和 Tab;Escape 会按下返回键。
- 应用和设备调用:
activate_app、query_app_state、press_keycode、hide_keyboard、is_keyboard_shown、current_activity、current_package、open_notifications、lock、unlock。 - 脚本:
mobile: clearApp(仅限设备所有者模式)、mobile: activateApp、mobile: pressKey、mobile: clickGesture、mobile: longClickGesture,以及能运行任意 Droidline 命令的mobile: droidline:
d.execute_script("mobile: droidline", {"cmd": "wait_idle"})
d.execute_script("mobile: droidline", {"cmd": "proxy_check"})
与 Appium 的不同
Droidline 不使用 ADB,所以需要 ADB 的功能都没有:安装和卸载应用、mobile: shell、推送和拉取文件、logcat 以及 WEBVIEW 上下文。此外: