## 移動手勢的自動化
盡管 Selenium WebDriver 的規范已經支持了一些移動交互,但它的參數并不總是能輕易映射到底層設備的自動化框架所提供的方法上(比如 iOS 上的 UIAutomation)。為此,Appium 在最新的規范([https://dvcs.w3.org/hg/webdriver/raw-file/tip/webdriver-spec.html#multiactions-1](https://dvcs.w3.org/hg/webdriver/raw-file/tip/webdriver-spec.html#multiactions-1))
中實現了新的觸摸操作和多點觸控 API。注意,這與早期版本中原始的 JSON Wire 協議里的觸摸操作 API 不同。
這些 API 允許你使用多個動作去建立任意的手勢。請查看對應語言的 Appium 客戶端文檔來查看使用這些 API 的示例。
**W3C 操作的注意事項**
某些驅動也可以使用[W3C 操作](https://www.w3.org/TR/webdriver1/#actions),例如 XCUITest、UIA2、Espresso 和 Windows。W3C 操作是在操作系統測試框架的最大限制下實現的。例如 WDA 無法處理零等待 [PR](https://github.com/appium/appium-xcuitest-driver/pull/753)。
[API 文檔](http://appium.io../../commands/interactions/actions/)(English),及每個客戶端的 API文檔可以幫助理解如何調用它們。
### 觸摸操作(TouchAction) / 多點觸控(MultiAction) API 概述
### 觸摸操作(TouchAction)
*TouchAction* 對象包含一連串的事件。
在所有的 appium 客戶端庫里,觸摸對象被創建并被賦予一連串的事件。
規范里可用的事件有:
* 短按(press)
* 釋放(release)
* 移動到(moveTo)
* 點擊(tap)
* 等待(wait)
* 長按(longPress)
* 取消(cancel)
* 執行(perform)
這是一個使用偽代碼創建一個動作的示例:
```center
TouchAction().press(el0).moveTo(el1).release()
```
上述模擬了一個用戶按下一個元素,滑動他的手指到另一個位置,然后將他的手指從屏幕上移開。
Appium按順序執行這一些列事件。你可以添加 `wait` 事件來控制事件的時長。
`moveTo` 的坐標現在與當前位置是 *絕對關系* 。例如,從 100,100 拖拽到 200,200 可以這樣實現:
```
.press(100,100) // 從 100,100 開始
.moveTo(200,200) // 通過絕對值 200,200,在 200,200 結束
```
Appium 客戶端庫有不同的實現方式,例如:你可以傳遞坐標或一個元素給 `moveTo` 事件。當坐標 _和_ 元素一起傳遞時,該坐標被理解為是相對于元素位置的相對坐標,而不是絕對位置。
調用 `perform` 事件發送全部的事件序列給 appium,觸摸手勢將在你的設備上執行。
### 多點觸控(MultiTouch)
*MultiTouch* 對象是觸摸操作的集合。
多點觸控手勢只有兩個方法,`add` 和 `perform`。
`add` 用于將不同的觸摸操作添加到當前的多點觸控中。
當 `perform` 執行時,被添加到多點觸控里的所有觸摸操作會被發送給 appium 并被執行,就像它們
同時發生一樣。Appium 會按序一個個執行觸摸事件,首先第一個事件,然后第二個,以此類推。
用兩只手指點擊的偽代碼示例:
```center
action0 = TouchAction().tap(el)
action1 = TouchAction().tap(el)
MultiAction().add(action0).add(action1).perform()
```
### 缺陷與解決方法
不幸的是,在iOS 7.0 - 8.x 的模擬器上存在著一個缺陷,ScrollViews、CollectionViews 和 TableViews 不能識別由 UIAutomation( Appium 在 iOS 底層所使用的框架)所創建的手勢。為了解決這個問題,我們提供了一個不同的入口函數 `scroll`,在大多數情況下,它能讓你對 view 執行你想要執行的操作,即滾動它!
**滾動**
為了允許使用這個特殊的手勢,我們重寫了驅動程序的 `execute` 和 `executeScript` 方法,并且給命令加上了 `mobile: ` 前綴。
看下面的示例:
為了進行滾動,將你想滾動的方向作為參數傳入。
```javascript
// javascript
driver.execute('mobile: scroll', {direction: 'down'})
```
```java
// java
JavascriptExecutor js = (JavascriptExecutor) driver;
HashMap<String, String> scrollObject = new HashMap<String, String>();
scrollObject.put("direction", "down");
js.executeScript("mobile: scroll", scrollObject);
```
```ruby
# ruby
execute_script 'mobile: scroll', direction: 'down'
```
```python
# python
driver.execute_script("mobile: scroll", {"direction": "down"})
```
```csharp
// c#
Dictionary<string, string> scrollObject = new Dictionary<string, string>();
scrollObject.Add("direction", "down");
((IJavaScriptExecutor)driver).ExecuteScript("mobile: scroll", scrollObject));
```
```php
$params = array(array('direction' => 'down'));
$driver->executeScript("mobile: scroll", $params);
```
使用方向和元素進行滾動的示例。
```javascript
// javascript
driver.execute('mobile: scroll', {direction: 'down', element: element.value.ELEMENT});
```
```java
// java
JavascriptExecutor js = (JavascriptExecutor) driver;
HashMap<String, String> scrollObject = new HashMap<String, String>();
scrollObject.put("direction", "down");
scrollObject.put("element", ((RemoteWebElement) element).getId());
js.executeScript("mobile: scroll", scrollObject);
```
```ruby
# ruby
execute_script 'mobile: scroll', direction: 'down', element: element.ref
```
```python
# python
driver.execute_script("mobile: scroll", {"direction": "down", element: element.getAttribute("id")})
```
```csharp
// c#
Dictionary<string, string> scrollObject = new Dictionary<string, string>();
scrollObject.Add("direction", "down");
scrollObject.Add("element", <element_id>);
((IJavaScriptExecutor)driver).ExecuteScript("mobile: scroll", scrollObject));
```
```php
$params = array(array('direction' => 'down', 'element' => element.GetAttribute("id")));
$driver->executeScript("mobile: scroll", $params);
```
**Swiping**
在 XCUITest 驅動上有一個特別的方法,它和 scrolling 類似。(見 https://developer.apple.com/reference/xctest/xcuielement)。
這個方法和 [Scrolling](#scrolling) 的 API 一致,只需用 "mobile: swipe" 替換 "mobile: scroll"。
**滑塊的自動化**
**iOS**
* **Java**
```java
// java
// 滑動值可以是代表0到1之間數字的字符串
// 例如,"0.1"代表10%,"1.0"代表100%
WebElement slider = driver.findElement(By.xpath("//window[1]/slider[1]"));
slider.sendKeys("0.1");
```
**Android**
在Android上與滑塊交互的最佳方式是使用觸摸操作(TouchActions)。
本文由 [NativeZhang](https://github.com/NativeZhang) 翻譯,由 [lihuazhang](https://github.com/lihuazhang) 校驗。
翻譯:@[Pandorym](https://github.com/Pandorym)
Last english version: 8c15ac66f18659974c31019ba1cdcd09cb25a275, Mar 12, 2019
- 關于TesterHome和MTSC
- 關于Appium
- 簡介
- Appium 客戶端
- 入門指南
- 已支持的平臺
- API 文檔
- Appium驅動
- XCUITest (iOS)
- XCUITest Real Devices (iOS)
- UIAutomation (iOS)
- UIAutomation Safari Launcher (iOS)
- UIAutomator (Android)
- UIAutomator2 (Android)
- Espresso (Android)
- Windows
- Mac
- Appium命令
- Status
- Execute Mobile Command
- Session
- Create
- End
- Get Session Capabilities
- Go Back
- Screenshot
- Source
- Timeouts
- Timeouts
- Implicit Wait
- Async Script
- Orientation
- Get Orientation
- Set Orientation
- Geolocation
- Get Geolocation
- Set Geolocation
- Logs
- Get Log Types
- Get Logs
- Events
- Log event
- Get events
- Settings
- Update Settings
- Get Device Settings
- Settings
- Update Settings
- Get Device Settings
- Execute Driver Script
- Device
- Activity
- Start Activity
- Current Activity
- Current Package
- App
- Install App
- Is App Installed
- Launch App
- Background App
- Close App
- Reset App
- Remove App
- Activate App
- Terminate App
- Get App State
- Get App Strings
- End Test Coverage
- Clipboard
- Get Clipboard
- Set Clipboard
- Emulator
- Power AC
- Power Capacity
- Files
- Push File
- Pull File
- Pull Folder
- Interactions
- Shake
- Lock
- Unlock
- Is Locked
- Rotate
- Keys
- Press keycode
- Long press keycode
- Hide Keyboard
- Is Keyboard Shown
- Network
- Toggle Airplane Mode
- Toggle Data
- Toggle WiFi
- Toggle Location Services
- Send SMS
- GSM Call
- GSM Signal
- GSM Voice
- Network Speed
- Performance Data
- Get Performance Data
- Performance Data Types
- Screen Recording
- Start Screen Recording
- Stop Screen Recording
- Simulator
- Perform Touch ID
- Toggle Touch ID Enrollment
- System
- Open Notifications
- System Bars
- System Time
- Display density
- Authentication
- Finger Print
- Element
- Find Element
- Find Elements
- Actions
- Click
- Send Keys
- Clear
- Attributes
- Text
- Name
- Attribute
- Selected
- Enabled
- Displayed
- Location
- Size
- Rect
- CSS Property
- Location in View
- Other
- Submit
- Active Element
- Equals Element
- Context
- Get Context
- Get All Contexts
- Set Context
- Interactions
- Mouse
- Move To
- Click
- Double Click
- Button Down
- Button Up
- Touch
- Single Tap
- Double Tap
- Move
- Touch Down
- Touch Up
- Long Press
- Scroll
- Flick
- Multi Touch Perform
- Touch Perform
- W3C Actions
- Web
- Window
- Set Window
- Close Window
- Get Handle
- Get Handles
- Get Title
- Get Window Size
- Set Window Size
- Get Window Position
- Set Window Position
- Maximize Window
- Navigation
- Go to URL
- Get URL
- Back
- Forward
- Refresh
- Storage
- Get All Cookies
- Set Cookie
- Delete Cookie
- Delete All Cookies
- Frame
- Switch to Frame
- Switch to Parent Frame
- Execute Async
- Execute
- 編寫 & 運行Appium腳本
- Running Tests
- Desired Capabilities
- The --default-capabilities flag
- Finding Elements
- Touch Actions
- CLI Arguments
- Server Security
- Web/Web Views
- Mobile Web Testing
- Automating Hybrid Apps
- Using ios-webkit-debug-proxy
- Using Chromedriver
- Image Comparison
- iOS
- Low-Level Insights on iOS Input Events
- XCUITest Mobile Gestures
- XCUITest Mobile App Management
- iOS Pasteboard Guide
- iOS Predicate Guide
- iOS Touch ID Guide
- iOS Install Certificate
- tvOS support
- Pushing/Pulling files
- Audio Capture
- Android
- Low-Level Insights on Android Input Events
- UiSelector Guide
- Espresso Datamatcher Guide
- Android Code Coverage Guide
- Activities Startup Troubleshooting Guide
- How To Execute Shell Commands On The Remote Device
- Android Device Screen Streaming
- How To Emulate IME Actions Generation
- How To Test Android App Bundle
- Other
- Reset Strategies
- Network Connection Guide
- Using Unicode with Appium
- Troubleshooting
- Tutorial
- Swipe Tutorial
- Screen
- Element
- Partial screen
- Simple
- Multiple scroll views
- Add scroll layout
- Tricks and Tips
- Screen
- Element
- Element search
- Fast
- Slow
- Guide
- 進階概念
- 定位圖像中的元素
- 使用定位元素的插件
- 遷移到 XCUITest
- 在 Appium 中使用 Selenium Grid
- Appium Logs Filtering
- 跨域 iframes
- 使用自定義 WDA 服務器
- 使用不同版本的 Xcode 運行
- The Event Timings API
- 并行測試的設置
- The Settings API
- Memory Collection
- 向Appium項目做貢獻
- 從源代碼運行 Appium
- 開發者概述
- 標準開發命令
- Appium 風格指南
- 如何編寫文檔
- Appium 包結構
- 鳴謝