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("Wi-Fi")')
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 같은 class. |
-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":"Wi-Fi"}}. |
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 컨텍스트입니다. 그 밖에는 다음과 같습니다.
send_keys는 Droidline의input처럼 입력란의 글자를 바꿔 넣습니다.- 제스처는 손가락 하나로만 합니다. 멀티터치 actions는 실패합니다.
appium:noReset과appium:fullReset은 무시합니다. 브리지가 스스로 데이터를 지우는 일은 없습니다.terminate_app과mobile: terminateApp은 unsupported operation 오류로 답합니다. 앱을 강제 종료하려면 설정 앱 레시피를 쓰세요.mobile: clearApp은clear_data를 실행하므로 기기 소유자 모드에서만 동작합니다.