Fix docs to work with jekyll

This commit is contained in:
bootstraponline
2014-04-09 18:14:14 -04:00
parent d566b7583f
commit 37fbb527df
46 changed files with 1007 additions and 526 deletions

View File

@@ -1,3 +1,8 @@
---
layout: default
title: readme
---
# Appium
> Appium是一个支持原生,混合和移动web apps的开源的跨平台测试框架工具

View File

@@ -1,3 +1,8 @@
---
layout: default
title: Intel 硬件加速器管理
---
# Intel® 硬件加速器管理
如果你发现android虚拟机太慢, 并且你的系统运行在Intel® 的cpu上. 那么你可以尝试下HAXM, HAXM能够让你充分利用硬件虚拟化技术来加速android模拟器

View File

@@ -1,3 +1,8 @@
---
layout: default
title: Android Coverage
---
Android 覆盖率需要使用模拟器或者 root 过的机器。使用 instrument target 构建应用,比如 `$ ant instrument`
`androidCoverage` 传给你设备的 capabilities并设置为你的 instrument 的 class。

View File

@@ -1,3 +1,8 @@
---
layout: default
title: Appium 服务关键字
---
Appium 服务关键字
==========

View File

@@ -1,3 +1,8 @@
---
layout: default
title: 名单
---
名单
=======

View File

@@ -1,3 +1,8 @@
---
layout: default
title: 元素定位与交互
---
元素定位与交互
=====================================
@@ -71,6 +76,7 @@ Ruby:
```ruby
@driver.find_element(:name, 'Go').click
```
Python:
```python

View File

@@ -1,3 +1,8 @@
---
layout: default
title: 使移动手势自动化
---
使移动手势自动化
==========================
当selenium webDriver 提供某些交互功能的支持时它的参数并不总是能很容易的映射到底层自动化设备比如ios中的UIAutomation所提供的功能。为此Appium在WebDriver 之上为移动手势增加了额外的命令和参数。
@@ -92,6 +97,7 @@
}]
}
```
在这个例子中,`tap`方法被调用,使用上面定义的`x` and `y`参数。
##示例代码
@@ -124,6 +130,7 @@
tapObject.put("element", ((RemoteWebElement) row).getId()); // 想要执行tap事件的元素id
js.executeScript("mobile: tap", tapObject);
```
```java
//在iOS app中如果UI 控件的visible属性为“false”通过元素的位置进行点击.
WebElement element = wd.findElement(By.xpath("//window[1]/scrollview[1]/image[1]"));
@@ -134,6 +141,7 @@
tapObject.put("duration", 0.1);
js.executeScript("mobile: tap", tapObject);
```
* **Python:**
```python
@@ -155,7 +163,7 @@
* **C#:**
```C#
```c#
Dictionary<String, Double> coords = new Dictionary<string, double>();
coords.Add("x", 12);
coords.Add("y", 12);
@@ -234,6 +242,7 @@
### 设置方向
* **WD.js:**
```js
driver.setOrientation("LANDSCAPE", function(err) {
// continue testing

View File

@@ -1,3 +1,8 @@
---
layout: default
title: Selenium Grid
---
Selenium Grid
======================

View File

@@ -1,3 +1,8 @@
---
layout: default
title: Appium grunt 命令
---
Appium grunt 命令
=============

View File

@@ -1,3 +1,8 @@
---
layout: default
title: 自动化混合应用
---
自动化混合应用
======================
@@ -23,6 +28,7 @@ appium 使用一个远程调试器建立连接来实现和 web 视图的交互
当在真机上运行用例时appium 无法直接访问 web 视图,所以我们需要通过 USB 线缆来建立连接。我们使用 [ios-webkit-debugger-proxy](https://github.com/google/ios-webkit-debug-proxy)建立连接。
使用 brew 安装最新的 ios-webkit-debug-proxy。在终端运行一下命令:
``` bash
# 如果你没有安装 brew 的话,先安装 brew。
> ruby -e "$(curl -fsSL https://raw.github.com/mxcl/homebrew/go/install)"
@@ -43,6 +49,7 @@ appium 使用一个远程调试器建立连接来实现和 web 视图的交互
```
一旦安装好了, 你就可以启动代理:
``` bash
# 将udid替换成你的设备的udid。确保端口 27753 没有被占用
# remote-debugger 将会使用这个端口。

9
docs/cn/index.md Normal file
View File

@@ -0,0 +1,9 @@
---
layout: default
title: Documentation
description: Appium v0.18.0 Chinese Documentation
---
- Documentation
{% include doc_list.md url="/docs/cn/0.18.0" %}

View File

@@ -1,3 +1,8 @@
---
layout: default
title: iOS Deploy
---
部署ios app 到手机上
=====================================
准备在真机上执行appium测试, 需要如下准备:
@@ -29,6 +34,7 @@ PROVISIONING_PROFILE 已经从可用的的命令中消失了,但还是有必
```
xcodebuild -sdk <iphoneos> -target <target_name> -configuration <Debug> CODE_SIGN_IDENTITY="iPhone Developer: Mister Smith" PROVISIONING_PROFILE="XXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX"
```
成功的话, app会构建到如下目录 ```<app_dir>/build/<configuration>-iphoneos/<app_name>.app```
## 用Fruitstrap进行部署
@@ -38,14 +44,19 @@ clone成功的话, 执行 ``make fruitstrap``
然后, 然后复制生成的 ``fruitstrap``到app的所在的目录或上级目录下。
运行fruitstrap 通过输入以下命令 (命令是否可用依赖于你fork的 fruitstrap):
```
./fruitstrap -d -b <PATH_TO_APP> -i <Device_UDID>
```
如果是为了持续集成,你可以发现很有用的方法来记录fruitstrap命令行和日志文件中的记录, 像这样:
```
./fruitstrap -d -b <PATH_TO_APP> -i <Device_UDID> 2>&1 | tee fruit.out
```
在node服务启动前fruitstrap进行需要被结束, 一个方法是扫描fruitstrap的输出来得知app完成启动。 有一个有效的方法是通过一个Rakefile 和一个 ``go_device.sh`` 脚本:
```
bundle exec rake ci:fruit_deploy_app | while read line ; do
echo "$line" | grep "text to identify successful launch"
@@ -58,6 +69,7 @@ bundle exec rake ci:fruit_deploy_app | while read line ; do
fi
done
```
一旦fruitstrap的进程被结束, node 服务就可以启动并且appium测试可以被执行!
下一步:

View File

@@ -1,3 +1,8 @@
---
layout: default
title: 自动化手机网页应用
---
自动化手机网页应用
======================
@@ -10,6 +15,7 @@
如果你打算在模拟器或真机上使用Appium的话你必须先开发Safari。
然后设置如下显示的这些信息以便于在设备中的Safari执行测试
```js
{
app: 'safari'
@@ -40,6 +46,7 @@
* <b>第六步:</b> 寻找并牢记你的<b>UUID</b>
现在你有了自己的profile文件可以在终端中输入如下的命令:
```bash
$ git clone https://github.com/appium/appium.git
$ cd appium
@@ -62,6 +69,7 @@ $ node /lib/server/main.js -U <UDID>
##### Java 举例
```java
//setup the web driver and launch the webview app.
DesiredCapabilities desiredCapabilities = new DesiredCapabilities();

View File

@@ -1,3 +1,8 @@
---
layout: default
title: 跨平台的移动测试方法
---
#### 跨平台的移动测试方法
##### 移动测试的重置方法reset
@@ -5,6 +10,7 @@
reset方法会重置待测应用的状态
Ruby + [appium_lib gem](https://github.com/appium/ruby_lib)
```ruby
mobile :reset
```

View File

@@ -1,3 +1,8 @@
---
layout: default
title: Appium 在真机上
---
Appium在真机上
======================
Appium已经初步支持真机测试。
@@ -28,6 +33,7 @@ Provisioning Profile
```
node . -U <UDID> --app <bundle_id>
```
这将会启动Appium并且开始在真机上测试应用。
疑问解答思路

View File

@@ -1,3 +1,8 @@
---
layout: default
title: 在 Linux 上运行 Appium
---
在 Linux 上运行 Appium
=======================

View File

@@ -1,3 +1,8 @@
---
layout: default
title: 在 Mac OS X 上使用 Appium
---
在 Mac OS X 上使用 Appium
=======

View File

@@ -1,3 +1,8 @@
---
layout: default
title: 在windows上运行appium
---
在windows上运行appium
=======================

View File

@@ -1,3 +1,8 @@
---
layout: default
title: 執行測試
---
執行測試
=============

View File

@@ -1,3 +1,8 @@
---
layout: default
title: Appium 服务器参数
---
Appium 服务器参数
==========

View File

@@ -1,3 +1,8 @@
---
layout: default
title: 触摸动作touch actions
---
# 触摸动作touch actions
@@ -14,6 +19,7 @@ new TouchActions(driver).longPress(imageView).perform();
Android 应用:
Java:
```java
WebElement element = wd.findElement(By.name("API Demo"));
JavascriptExecutor js = (JavascriptExecutor) wd;
@@ -23,6 +29,7 @@ js.executeScript("mobile: longClick", tapObject);
```
Python:
```python
element = wd.find_element_by_xpath("your_element_xpath")
wd.execute_script("mobile: longClick",{ "touchCount": 1, "x": 0, "y": 300, "element":element.id })

View File

@@ -1,3 +1,8 @@
---
layout: default
title: Appium 故障调试
---
Appium 故障调试
======================

View File

@@ -1,11 +1,17 @@
---
title: Intel Hardware Accelerated Execution Manager
layout: default
---
# Intel® Hardware Accelerated Execution Manager
If you find the android emulator a slow and your system runs on an Intel® cpu, you can check out HAXM. HAXM let's you leverage your hardware for virtualization accelerating the emulator.
If you find the android emulator a slow and your system runs on an Intel®
cpu, you can check out HAXM. HAXM let's you leverage your hardware for
virtualization accelerating the emulator.
* To install HAXM open the Android SDK Manager, you will find the package under Extras.
* You can find all relevent documentation on [Intel's website][1]
* You can find all relevant documentation on [Intel's website][1]
* This will require an x86 emulator image
* Use Intel's package to install HAXM; The Android SDK Manager appears to not do so successfully.
[1]: http://software.intel.com/en-us/articles/intel-hardware-accelerated-execution-manager/ "Hax"
[2]: http://software.intel.com/en-us/search/site/language/en?query=Intel%20Hardware%20Accelerated%20Execution%20Manager%20%28HAXM%29 "Hax all"
[1]: http://software.intel.com/en-us/articles/intel-hardware-accelerated-execution-manager/

View File

@@ -1,14 +1,24 @@
Android coverage requires the emulator or a rooted device. Build your app using the instrument target, for example `$ ant instrument`
---
title: Android coverage
layout: default
---
Pass `androidCoverage` to your device capabilities and set it to your instrumentation class.
Android coverage requires the emulator or a rooted device. Build your app
using the instrument target, for example `$ ant instrument`
Pass `androidCoverage` to your device capabilities and set it to your
instrumentation class.
```ruby
caps = { androidCoverage: 'com.example.pkg/com.example.pkg.instrumentation.MyInstrumentation' }
```
Appium will start your app like this: `adb shell am instrument -e coverage true -w com.example.pkg/com.example.pkg.instrumentation.MyInstrumentation`
Appium will start your app like this:
After your test completes, it's time to end the coverage collection and pull the coverage.ec file from the device.
`adb shell am instrument -e coverage true -w com.example.pkg/com.example.pkg.instrumentation.MyInstrumentation`
After your test completes, it's time to end the coverage collection and pull
the coverage.ec file from the device.
```ruby
mobile :endCoverage, intent: 'com.example.pkg.END_EMMA', path: '/mnt/sdcard/coverage.ec'
@@ -101,6 +111,9 @@ public class MyInstrumentation extends Instrumentation {
#### Reports
`ant instrument` generates a `coverage.em` file. The `mobile :endCoverage` will download the coverage.ec file for that particular run. Note that you can have any number of coverage.ec files. To merge them all together into a report, use this command:
`ant instrument` generates a `coverage.em` file. The `mobile :endCoverage`
will download the coverage.ec file for that particular run. Note that you can
have any number of coverage.ec files. To merge them all together into a
report, use this command:
> java -cp /path/to/android-sdk-macosx/tools/lib/emma_device.jar emma report -r html -in coverage.em,coverage0.ec,coverage1.ec -sp /path/to/your-app/src

View File

@@ -1,3 +1,8 @@
---
title: Appium server capabilities
layout: default
---
Appium server capabilities
==========

View File

@@ -1,3 +1,8 @@
---
title: Credits
layout: default
---
Credits
=======

View File

@@ -1,29 +1,42 @@
---
title: Finding and interacting with elements
layout: default
---
Finding and interacting with elements
=====================================
Appium supports a subset of the WebDriver locator strategies:
* find by "tag name" (i.e., ui component type)
* find by "name" (i.e., the text, label, or developer-generated ID a.k.a 'accessibilityIdentifier' of an element)
NOTE: the "name" locator strategy will be deprecated on mobile devices, and will not be a part of Appium v1.0
* find by "xpath" (i.e., an abstract representation of a path to an element, with certain constraints)
* find by "name" (i.e., the text, label, or developer-generated ID a.k.a
'accessibilityIdentifier' of an element)
NOTE: the "name" locator strategy will be deprecated on mobile devices,
and will not be a part of Appium v1.0
* find by "xpath" (i.e., an abstract representation of a path to an element,
with certain constraints)
Appium additionally supports some of the [Mobile JSON Wire Protocol](https://code.google.com/p/selenium/source/browse/spec-draft.md?repo=mobile) locator strategies
* `-ios uiautomation`: a string corresponding to a recursive element search using the UIAutomation library (iOS-only)
* `-android uiautomator`: a string corresponding to a recursive element search using the UiAutomator Api (Android-only)
* `accessibility id`: a string corresponding to a recursive element search using the Id/Name that the native Accessibility options utilize.
* `-ios uiautomation`: a string corresponding to a recursive element search
using the UIAutomation library (iOS-only)
* `-android uiautomator`: a string corresponding to a recursive element
search using the UiAutomator Api (Android-only)
* `accessibility id`: a string corresponding to a recursive element search
using the Id/Name that the native Accessibility options utilize.
###Tag name mapping
You can use the direct UIAutomation component type name for the tag name, or use the simplified mapping (used in some examples below) found here:
You can use the direct UIAutomation component type name for the tag name,
or use the simplified mapping (used in some examples below) found here:
https://github.com/appium/appium-uiauto/blob/master/uiauto/lib/mechanic.js#L30
Issues
------
There's a known issue with table cell elements becoming invalidated before there's time to interact with them. We're working on a fix
There's a known issue with table cell elements becoming invalidated before
there's time to interact with them. We're working on a fix
Examples
--------
@@ -79,6 +92,7 @@ Ruby:
```ruby
@driver.find_element(:name, 'Go').click
```
Python:
```python
@@ -143,7 +157,8 @@ driver.element('-android uiautomator', 'new UiSelector().clickable(true)').getAt
# FindAndAct<a name="findandact"></a>
If you want, you can find and act on an element in a single command (iOS-only).
For example, you can find and click on an element in one call to Appium, using a special `mobile: findAndAct` command.
For example, you can find and click on an element in one call to Appium,
using a special `mobile: findAndAct` command.
Python:
@@ -167,20 +182,29 @@ Note: driver.execute_script() is explained in [Automating Mobile Gestures: Alter
Using The Appium Inspector To Locate Elements
--------
Appium provides you with a neat tool that allows you to find the the elements you're looking for without leaving the Appium app. With the Appium Inspector (the i symbol next to the start test button) you can find any element and it's name by either clicking the element on the preview page provided, or locating it in the UI navigator.
Appium provides you with a neat tool that allows you to find the the elements
you're looking for without leaving the Appium app. With the Appium Inspector
(the i symbol next to the start test button) you can find any element and
it's name by either clicking the element on the preview page provided,
or locating it in the UI navigator.
### Overview
The Appium inspector has a simple layout, complete with a UI navigator, a preview, and record and refresh buttons, and interaction tools.
The Appium inspector has a simple layout, complete with a UI navigator,
a preview, and record and refresh buttons, and interaction tools.
![Step 1](https://raw.github.com/appium/appium/master/assets/InspectorImages/Overview.png)
### Example
After launching the Appium Inspector (you can do this by clicking the small "i" button in the top right of the app) you can locate any element in the preview. In this test, I'm looking for the id of the "show alert" button.
After launching the Appium Inspector (you can do this by clicking the small
"i" button in the top right of the app) you can locate any element in the
preview. In this test, I'm looking for the id of the "show alert" button.
![Step 1](https://raw.github.com/appium/appium/master/assets/InspectorImages/Step1.png)
To find the id of this button, I click the "show alert" button in the inspector preview. The Appium inspector then highlights the element in the UI navigator, showing me both the id and element type of the button I clicked.
To find the id of this button, I click the "show alert" button in the
inspector preview. The Appium inspector then highlights the element in the UI
navigator, showing me both the id and element type of the button I clicked.
![Step 1](https://raw.github.com/appium/appium/master/assets/InspectorImages/Step2.png)
![Step 1](https://raw.github.com/appium/appium/master/assets/InspectorImages/Step2.png)

375
docs/en/gestures.md Normal file
View File

@@ -0,0 +1,375 @@
---
title: Automating mobile gestures
layout: default
---
Automating mobile gestures
==========================
While the Selenium WebDriver spec has support for certain kinds of mobile
interaction, its parameters are not always easily mappable to the
functionality that the underlying device automation (like UIAutomation in the
case of iOS) provides. To that end, Appium augments the WebDriver spec with
extra commands and parameters for mobile gestures:
* **tap** (on screen or on element) with options:
* how many fingers
* how long to tap
* how many taps
* where precisely to tap on the screen or element
* **flick** (on screen or on element) with options:
* how many fingers
* where to start the flick on screen or element
* where to end the flick on screen or element
* **swipe/drag** (on screen or on element) with options:
* how many fingers
* how long the swipe/drag takes in seconds
* where to start the swipe on screen or element
* where to end the swipe on screen or element
* **scroll to** (element)
* **slider**
* **shake**
* **longTap** (element)
* set the **orientation** with option:
* new orientation (landscape or portrait)
## JSON Wire Protocol server extensions
Here are the endpoints with which we have implemented these additions to the
spec.
**Note on coordinates:** All the X and Y parameters listed below can be used
in two ways. If they are between 0 and 1 (e.g., 0.5), they are taken to be
percentage of screen or element size. In other words,
`{x: 0.5, y: 0.25}` means a coordinate that is 50% from the left side of the
screen/element, and 25% from the top of the screen/element. If the values are
greater than 1, they are taken as pixels. So, `{x: 100,
y: 300}` means a coordinate that is 100 pixels from the left and 300 from
the top of the screen/element.
**Note on performing actions on screen vs elements:** These methods all take
an optional `element` parameter. If present, this is taken to be the ID of an
element which has already been retrieved. So in this case,
the coordinates will be taken to refer to the rectangle of that element only
. So `{x: 0.5, y: 0.5, element: '3'}` means "the exact middle point of the
element with ID '3'".
* `POST session/:sessionId/touch/tap` - perform a tap on the screen or an element
* URL Parameter: sessionId of session to route to
* JSON parameters:
* `tapCount` (optional, default `1`): how many times to tap
* `touchCount` (optional, default `1`): how many fingers to tap with
* `duration` (optional, default `0.1`): how long (in seconds) to tap
* `x` (optional, default `0.5`): x coordinate to tap (in pixels or relative units)
* `y` (optional, default `0.5`): y coordinate to tap (in pixels or relative units)
* `element` (optional): ID of element to scope this command to
* `POST session:/sessionId/touch/flick_precise` - perform a flick on the screen or an element
* URL Parameter: sessionId of session to route to
* JSON parameters:
* `touchCount` (optional, default `1`): how many fingers to flick with
* `startX` (optional, default `0.5`): x coordinate where flick begins (in pixels or relative units)
* `startY` (optional, default `0.5`): y coordinate where flick begins (in pixels or relative units)
* `endX` (required): x coordinate where flick ends (in pixels or relative units)
* `endY` (required): y coordinate where flick ends (in pixels or relative units)
* `element` (optional): ID of element to scope this command to
* `POST session:/sessionId/touch/swipe` - perform a swipe/drag on the screen or an element
* URL Parameter: sessionId of session to route to
* JSON parameters:
* `touchCount` (optional, default `1`): how many fingers to flick with
* `startX` (optional, default `0.5`): x coordinate where swipe begins (in pixels or relative units)
* `startY` (optional, default `0.5`): y coordinate where swipe begins (in pixels or relative units)
* `endX` (required): x coordinate where swipe ends (in pixels or relative units)
* `endY` (required): y coordinate where swipe ends (in pixels or relative units)
* `duration` (optional, default `0.8`): time (in seconds) to spend performing the swipe/drag
* `element` (optional): ID of element to scope this command to
**Note on setting orientation:** Setting the orientation takes different
parameters than the tap, flick, and swipe methods. This action is performed
by setting the orientation of the browser to "LANDSCAPE" or "PORTRAIT". The
alternative access method below does not apply to setting orientation.
* `POST /session/:sessionId/orientation` - set the orientation of the browser
* URL Parameter: sessionId of session to route to
* JSON parameters:
* `orientation` (required): new orientation, either "LANDSCAPE" or "PORTRAIT"
## Alternative access method
Extending the JSON Wire Protocol is great, but it means that the various
WebDriver language bindings will have to implement access to these endpoints
in their own way. Naturally, this will take different amounts of time
depending on the project. We have instituted a way to get around this delay,
by using `driver.execute()` with special parameters.
`POST session/:sessionId/execute` takes two JSON parameters:
* `script` (usually a snippet of javascript)
* `args` (usually an array of arguments passed to that snippet in the javascript engine)
In the case of these new mobile methods, `script` must be one of:
* `mobile: tap`
* `mobile: flick`
* `mobile: swipe`
* `mobile: scrollTo`
* `mobile: scroll`
* `mobile: shake`
(The `mobile:` prefix allows us to route these requests to the appropriate
endpoint).
And `args` will be an array with one element: a Javascript object defining
the parameters for the corresponding function. So, let's say I want to call
`tap` on a certain screen position. I can do so by calling `driver.execute`
with these JSON parameters:
```json
{
"script": "mobile: tap",
"args": [{
"x": 0.8,
"y": 0.4
}]
}
```
In this example, our new `tap` method will be called with the `x` and `y`
params as described above.
## Code examples
In these examples, note that the element parameter is always optional.
### Tap
* **WD.js:**
```js
driver.elementsByTagName('tableCell', function(err, els) {
var tapOpts = {
x: 150 // in pixels from left
, y: 30 // in pixels from top
, element: els[4].value // the id of the element we want to tap
};
driver.execute("mobile: tap", [tapOpts], function(err) {
// continue testing
});
});
```
* **Java:**
```java
WebElement row = driver.findElements(By.tagName("tableCell")).get(4);
JavascriptExecutor js = (JavascriptExecutor) driver;
HashMap<String, Double> tapObject = new HashMap<String, Double>();
tapObject.put("x", 150); // in pixels from left
tapObject.put("y", 30); // in pixels from top
tapObject.put("element", ((RemoteWebElement) row).getId()); // the id of the element we want to tap
js.executeScript("mobile: tap", tapObject);
```
```java
//In iOS app, if UI element visbile property is "false".
//Using element location tap on it.
WebElement element = wd.findElement(By.xpath("//window[1]/scrollview[1]/image[1]"));
JavascriptExecutor js = (JavascriptExecutor) wd;
HashMap<String, Double> tapObject = new HashMap<String, Double>();
tapObject.put("x", (double) element.getLocation().getX());
tapObject.put("y", (double) element.getLocation().getY());
tapObject.put("duration", 0.1);
js.executeScript("mobile: tap", tapObject);
```
* **Python:**
```python
driver.execute_script("mobile: tap", {"touchCount":"1", "x":"0.9", "y":"0.8", "element":element.id})
```
* **Ruby:**
```ruby
@driver.execute_script 'mobile: tap', :x => 150, :y => 30
```
* **Ruby:**
```ruby
b = @driver.find_element :name, 'Sign In'
@driver.execute_script 'mobile: tap', :element => b.ref
```
* **C#:**
```c#
Dictionary<String, Double> coords = new Dictionary<string, double>();
coords.Add("x", 12);
coords.Add("y", 12);
driver.ExecuteScript("mobile: tap", coords);
```
### Flick
* **WD.js:**
```js
// options for a 2-finger flick from the center of the screen to the top left
var flickOpts = {
endX: 0
, endY: 0
, touchCount: 2
};
driver.execute("mobile: flick", [flickOpts], function(err) {
// continue testing
});
```
* **Java:**
```java
JavascriptExecutor js = (JavascriptExecutor) driver;
HashMap<String, Double> flickObject = new HashMap<String, Double>();
flickObject.put("endX", 0);
flickObject.put("endY", 0);
flickObject.put("touchCount", 2);
js.executeScript("mobile: flick", flickObject);
```
### Swipe
*Note*: Swiping is unfortunately broken in iOS7, because of a bug in Apple's
frameworks. For iOS7, see `mobile: scroll` as a workaround that works for most
cases.
* **WD.js:**
```js
// options for a slow swipe from the right edge of the screen to the left
var swipeOpts = {
startX: 0.95
, startY: 0.5
, endX: 0.05
, endY: 0.5
, duration: 1.8
};
driver.execute("mobile: swipe", [swipeOpts], function(err) {
// continue testing
});
```
* **Java:**
```java
JavascriptExecutor js = (JavascriptExecutor) driver;
HashMap<String, Double> swipeObject = new HashMap<String, Double>();
swipeObject.put("startX", 0.95);
swipeObject.put("startY", 0.5);
swipeObject.put("endX", 0.05);
swipeObject.put("endY", 0.5);
swipeObject.put("duration", 1.8);
js.executeScript("mobile: swipe", swipeObject);
```
### Scroll
* **WD.js:**
```js
// scroll the view down
driver.execute("mobile: scroll", [{direction: 'down'}], function(err) {
// continue testing
});
```
* **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);
```
### Slider
**iOS**
* **Java**
```java
// slider values can be string representations of numbers between 0 and 1
// e.g., "0.1" is 10%, "1.0" is 100%
WebElement slider = wd.findElement(By.xpath("//window[1]/slider[1]"));
slider.sendKeys("0.1");
```
**Android**
The best way to interact with the slider on Android is with the 'mobile:
tap' gesture. It is difficult to find a reliable way to set a specific
percentage that works on all screen sizes, however. Therefore,
it is recommended to write tests that focus on minimum, 50%, and maximum.
* **Ruby**
```ruby
# 0%
@driver.execute_script 'mobile: tap', :x =>slider.location.x, :y =>slider.location.y
# 100%
@driver.execute_script 'mobile: tap', :x =>slider.location.x + slider.size.width - 1, :y =>slider.location.y
# 50%
slider.click
```
### Set orientation
* **WD.js:**
```js
driver.setOrientation("LANDSCAPE", function(err) {
// continue testing
});
```
* **Python:**
```python
driver.orientation = "LANDSCAPE"
```
### Scroll To
```ruby
b = @driver.find_element :name, 'Sign In'
@driver.execute_script 'mobile: scrollTo', :element => b.ref
```
```java
JavascriptExecutor js = (JavascriptExecutor) driver;
WebElement element = wd.findElement(By.name("Log In"));;
HashMap<String, String> scrollToObject = new HashMap<String, String>();
scrollToObject.put("element",((RemoteWebElement) element).getId());
js.executeScript("mobile: scrollTo", scrollToObject);
```
### longTap
* **c#**
```c#
// long tap an element
//
Dictionary<string, object> parameters = new Dictionary<string, object>();
parameters.Add("using", _attributeType);
parameters.Add("value", _attribute);
Response response = rm.executescript(DriverCommand.FindElement, parameters);
Dictionary<string, object> elementDictionary = response.Value as Dictionary<string, object>;
string id = null;
if (elementDictionary != null)
{
id = (string)elementDictionary["ELEMENT"];
}
IJavaScriptExecutor js = (IJavaScriptExecutor)remoteDriver;
Dictionary<String, String> longTapObject = new Dictionary<String, String>();
longTapObject.Add("element", id);
js.ExecuteScript("mobile: longClick", longTapObject);
```

View File

@@ -1,15 +1,27 @@
---
title: Selenium Grid
layout: default
---
Selenium Grid
======================
You are able to register your appium server with a local grid by using the <b>"--nodeconfig"</b> server parameter.
You are able to register your appium server with a local grid by using the
<b>"--nodeconfig"</b> server parameter.
```bash
> node . -V --nodeconfig /path/to/nodeconfig.json
```
In the node config file you have to define the <b>"browserName"</b>, <b>"version"</b> and <b>"platform"</b> and based on these parameters the grid will re-direct your test to the right device. You will also need to configure you <b>host</b> details and the <b>selenium grid</b> details. For a full list of all parameters and descriptions look <a href="http://code.google.com/p/selenium/source/browse/java/server/src/org/openqa/grid/common/defaults/GridParameters.properties">here</a>.
In the node config file you have to define the <b>"browserName"</b>,
<b>"version"</b> and <b>"platform"</b> and based on these parameters the grid
will re-direct your test to the right device. You will also need to
configure you <b>host</b> details and the <b>selenium grid</b> details. For
a full list of all parameters and descriptions look
[here](http://code.google.com/p/selenium/source/browse/java/server/src/org/openqa/grid/common/defaults/GridParameters.properties)
Once you start the appium server and it registers with the grid, you will see your device on the grid console page:
Once you start the appium server and it registers with the grid,
you will see your device on the grid console page:
"http://<b>\<grid-ip-adress\></b>:<b>\<grid-port\></b>/grid/console"
@@ -43,6 +55,6 @@ Once you start the appium server and it registers with the grid, you will see yo
}
```
Valid platforms are listed <a href="http://selenium.googlecode.com/git/docs/api/java/org/openqa/selenium/Platform.html">here</a>
Valid platforms are listed [here](http://selenium.googlecode.com/git/docs/api/java/org/openqa/selenium/Platform.html)
If `url`, `host`, and `port` are not given, the config will be auto updated to point to localhost:whatever-port-Appium-started-on.
If `url`, `host`, and `port` are not given, the config will be auto updated to point to localhost:whatever-port-Appium-started-on.

View File

@@ -1,3 +1,8 @@
---
title: Appium grunt commands
layout: default
---
Appium grunt commands
=============
@@ -30,5 +35,4 @@ By default, `grunt buildApp` builds apps using the iPhone 6.1 simulator SDK.
You can overwrite the simulator by passing another SDK to grunt (to figure out
which SDKs you have available, try `xcodebuild -showsdks`:
> grunt buildApp:UICatalog:iphonesimulator6.0
> grunt buildApp:UICatalog:iphonesimulator6.0

View File

@@ -1,7 +1,18 @@
---
title: Automating hybrid apps
layout: default
---
Automating hybrid apps
======================
One of the core principles of Appium is that you shouldn't have to change your app to test it. In line with that methodology, it is possible to test hybrid web apps (e.g., the "UIWebView" elements in an iOS app) the same* way you can with Selenium for web apps. There is a bit of technical complexity required so that Appium knows whether you want to automate the native aspects of the app or the web views, but thankfully, we can stay within the WebDriver protocol for everything.
One of the core principles of Appium is that you shouldn't have to change
your app to test it. In line with that methodology, it is possible to test
hybrid web apps (e.g., the "UIWebView" elements in an iOS app) the same* way
you can with Selenium for web apps. There is a bit of technical complexity
required so that Appium knows whether you want to automate the native aspects
of the app or the web views, but thankfully, we can stay within the
WebDriver protocol for everything.
* [Hybrid iOS apps](#ios)
* [Hybrid Android apps](#android)
@@ -14,14 +25,31 @@ Here are the steps required to talk to a web view in your Appium test:
1. Navigate to a portion of your app where a web view is active
1. Call [GET session/:sessionId/window_handles](http://code.google.com/p/selenium/wiki/JsonWireProtocol#/session/:sessionId/window_handles)
1. This returns a list of web view ids we can access
1. Call [POST session/:sessionId/window](http://code.google.com/p/selenium/wiki/JsonWireProtocol#/session/:sessionId/window) with the id of the web view you want to access
1. (This puts your Appium session into a mode where all commands are interpreted as being intended for automating the web view, rather than the native portion of the app. For example, if you run getElementByTagName, it will operate on the DOM of the web view, rather than return UIAElements. Of course, certain WebDriver methods only make sense in one context or another, so in the wrong context you will receive an error message).
1. To stop automating in the web view context and go back to automating the native portion of the app, simply call `"mobile: leaveWebView"` with execute_script to leave the web frame.
1. Call [POST session/:sessionId/window](http://code.google.com/p/selenium/wiki/JsonWireProtocol#/session/:sessionId/window)
with the id of the web view you want to access
1. (This puts your Appium session into a mode where all commands are
interpreted as being intended for automating the web view,
rather than the native portion of the app. For example,
if you run getElementByTagName, it will operate on the DOM of the web view,
rather than return UIAElements. Of course, certain WebDriver methods only
make sense in one context or another, so in the wrong context you will
receive an error message).
1. To stop automating in the web view context and go back to automating the
native portion of the app, simply call `"mobile: leaveWebView"` with
execute_script to leave the web frame.
## Execution against a real iOS device
To interrogate and interact with a web view appium establishes a connection using a remote debugger. When executing the examples below against a simulator this connection can be established directly as the simulator and the appium server are on the same machine. When executing against a real device appium is unable to access the web view directly. Therefore the connection has to be established through the USB lead. To establish this connection we use the [ios-webkit-debugger-proxy](https://github.com/google/ios-webkit-debug-proxy).
To interrogate and interact with a web view appium establishes a connection
using a remote debugger. When executing the examples below against a
simulator this connection can be established directly as the simulator and
the appium server are on the same machine. When executing against a real
device appium is unable to access the web view directly. Therefore the
connection has to be established through the USB lead. To establish this
connection we use the [ios-webkit-debugger-proxy](https://github.com/google/ios-webkit-debug-proxy).
To install the latest tagged version of the ios-webkit-debug-proxy using
brew, run the following commands in the terminal:
To install the latest tagged version of the ios-webkit-debug-proxy using brew, run the following commands in the terminal:
``` bash
# The first command is only required if you don't have brew installed.
> ruby -e "$(curl -fsSL https://raw.github.com/mxcl/homebrew/go/install)"
@@ -29,7 +57,9 @@ To install the latest tagged version of the ios-webkit-debug-proxy using brew, r
> brew install ios-webkit-debug-proxy
```
You can also install the latest proxy by cloning it from git and installing it yourself:
You can also install the latest proxy by cloning it from git and installing
it yourself:
``` bash
# Please be aware that this will install the proxy with the latest code (and not a tagged version).
> git clone https://github.com/google/ios-webkit-debug-proxy.git
@@ -41,6 +71,7 @@ You can also install the latest proxy by cloning it from git and installing it y
```
Once installed you can start the proxy with the following command:
``` bash
# Change the udid to be the udid of the attached device and make sure to set the port to 27753
# as that is the port the remote-debugger uses.
@@ -79,28 +110,28 @@ Once installed you can start the proxy with the following command:
## Wd.java Code example
```java
//setup the web driver and launch the webview app.
DesiredCapabilities desiredCapabilities = new DesiredCapabilities();
desiredCapabilities.setCapability("device", "iPhone Simulator");
desiredCapabilities.setCapability("app", "http://appium.s3.amazonaws.com/WebViewApp6.0.app.zip");
URL url = new URL("http://127.0.0.1:4723/wd/hub");
RemoteWebDriver remoteWebDriver = new RemoteWebDriver(url, desiredCapabilities);
//switch to the latest web view
for(String winHandle : remoteWebDriver.getWindowHandles()){
remoteWebDriver.switchTo().window(winHandle);
}
//Interact with the elements on the guinea-pig page using id.
WebElement div = remoteWebDriver.findElement(By.id("i_am_an_id"));
Assert.assertEquals("I am a div", div.getText()); //check the text retrieved matches expected value
remoteWebDriver.findElement(By.id("comments")).sendKeys("My comment"); //populate the comments field by id.
//leave the webview to go back to native app.
remoteWebDriver.executeScript("mobile: leaveWebView");
//close the app.
remoteWebDriver.quit();
//setup the web driver and launch the webview app.
DesiredCapabilities desiredCapabilities = new DesiredCapabilities();
desiredCapabilities.setCapability("device", "iPhone Simulator");
desiredCapabilities.setCapability("app", "http://appium.s3.amazonaws.com/WebViewApp6.0.app.zip");
URL url = new URL("http://127.0.0.1:4723/wd/hub");
RemoteWebDriver remoteWebDriver = new RemoteWebDriver(url, desiredCapabilities);
//switch to the latest web view
for(String winHandle : remoteWebDriver.getWindowHandles()){
remoteWebDriver.switchTo().window(winHandle);
}
//Interact with the elements on the guinea-pig page using id.
WebElement div = remoteWebDriver.findElement(By.id("i_am_an_id"));
Assert.assertEquals("I am a div", div.getText()); //check the text retrieved matches expected value
remoteWebDriver.findElement(By.id("comments")).sendKeys("My comment"); //populate the comments field by id.
//leave the webview to go back to native app.
remoteWebDriver.executeScript("mobile: leaveWebView");
//close the app.
remoteWebDriver.quit();
```
## Wd.rb Code example using cucumber
@@ -119,9 +150,11 @@ capabilities =
}
@driver = Selenium::WebDriver.for(:remote, :desired_capabilities => capabilities, :url => SERVER_URL)
## I switch to the last window because its always the webview in our case, in other cases you may need to specify a window number
## View the appium logs while running @driver.window_handles to figure out which window is the one you want and find the associated number
## Then switch to it using @driver.switch_to_window("6")
# I switch to the last window because its always the webview in our case,
# in other cases you may need to specify a window number
# View the appium logs while running @driver.window_handles to figure out
# which window is the one you want and find the associated number
# Then switch to it using @driver.switch_to_window("6")
Given(/^I switch to webview$/) do
webview = @driver.window_handles.last
@@ -138,21 +171,41 @@ And(/^I click a webview button $/) do
@driver.find_element(:css, ".green_button").click
end
```
#### Troubleshooting Webview with Ruby:
I created a quick function in my helper class to find web elements no matter what window its in (this is useful if your webview id changes or if you are using the same codebase to test android and ios)
https://gist.github.com/feelobot/7309729
I created a quick function in [my helper class](https://gist.github.com/feelobot/7309729)
to find web elements no matter what window its in (this is useful if your
webview id changes or if you are using the same codebase to test android and
ios)
<a name="android"></a>Automating hybrid Android apps
--------------------------
Appium comes with built-in hybrid support via Chromedriver. Appium also uses Selendroid under the hood for webview support on devices older than 4.4. (In that case, you'll want to specify `"device": "selendroid"` as a desired capability). Then:
Appium comes with built-in hybrid support via Chromedriver. Appium also uses
Selendroid under the hood for webview support on devices older than 4.4. (In
that case, you'll want to specify `"device": "selendroid"` as a desired
capability). Then:
1. Navigate to a portion of your app where a web view is active
1. Call [POST session/:sessionId/window](http://code.google.com/p/selenium/wiki/JsonWireProtocol#/session/:sessionId/window) with the string "WEBVIEW" as the window handle, e.g., `driver.window("WEBVIEW")`.
1. (This puts your Appium session into a mode where all commands are interpreted as being intended for automating the web view, rather than the native portion of the app. For example, if you run getElementByTagName, it will operate on the DOM of the web view, rather than return UIAElements. Of course, certain WebDriver methods only make sense in one context or another, so in the wrong context you will receive an error message).
1. To stop automating in the web view context and go back to automating the native portion of the app, simply call `window` again with the string "NATIVE_APP", e.g., `driver.window("NATIVE_APP")`.
1. Call [POST session/:sessionId/window](http://code.google.com/p/selenium/wiki/JsonWireProtocol#/session/:sessionId/window)
with the string "WEBVIEW" as the window handle, e.g., `driver.window("WEBVIEW")`.
1. (This puts your Appium session into a mode where all commands are
interpreted as being intended for automating the web view,
rather than the native portion of the app. For example,
if you run getElementByTagName, it will operate on the DOM of the web view,
rather than return UIAElements. Of course, certain WebDriver methods only
make sense in one context or another, so in the wrong context you will
receive an error message).
1. To stop automating in the web view context and go back to automating the
native portion of the app, simply call `window` again with the string
"NATIVE_APP", e.g., `driver.window("NATIVE_APP")`.
Note: We could have used the same strategy as above for leaving the webview (calling `mobile: leaveWebView`), however Selendroid uses the `WEBVIEW`/`NATIVE_APP` window setting strategy, which also works with regular Appium hybrid support, so we show that here for parity.
Note: We could have used the same strategy as above for leaving the webview
(calling `mobile: leaveWebView`), however Selendroid uses the
`WEBVIEW`/`NATIVE_APP` window setting strategy, which also works with regular
Appium hybrid support, so we show that here for parity.
## Wd.js Code example
@@ -175,24 +228,24 @@ driver.window("WEBVIEW", function(err) { // choose the only available view
## Wd.java Code example
```java
//setup the web driver and launch the webview app.
DesiredCapabilities desiredCapabilities = new DesiredCapabilities();
desiredCapabilities.setCapability("device", "Selendroid");
desiredCapabilities.setCapability("app", "/path/to/some.apk");
URL url = new URL("http://127.0.0.1:4723/wd/hub");
RemoteWebDriver remoteWebDriver = new RemoteWebDriver(url, desiredCapabilities);
//switch to the web view
remoteWebDriver.switchTo().window("WEBVIEW");
//Interact with the elements on the guinea-pig page using id.
WebElement div = remoteWebDriver.findElement(By.id("i_am_an_id"));
Assert.assertEquals("I am a div", div.getText()); //check the text retrieved matches expected value
remoteWebDriver.findElement(By.id("comments")).sendKeys("My comment"); //populate the comments field by id.
//leave the webview to go back to native app.
remoteWebDriver.switchTo().window("NATIVE_APP");
//close the app.
remoteWebDriver.quit();
```
//setup the web driver and launch the webview app.
DesiredCapabilities desiredCapabilities = new DesiredCapabilities();
desiredCapabilities.setCapability("device", "Selendroid");
desiredCapabilities.setCapability("app", "/path/to/some.apk");
URL url = new URL("http://127.0.0.1:4723/wd/hub");
RemoteWebDriver remoteWebDriver = new RemoteWebDriver(url, desiredCapabilities);
//switch to the web view
remoteWebDriver.switchTo().window("WEBVIEW");
//Interact with the elements on the guinea-pig page using id.
WebElement div = remoteWebDriver.findElement(By.id("i_am_an_id"));
Assert.assertEquals("I am a div", div.getText()); //check the text retrieved matches expected value
remoteWebDriver.findElement(By.id("comments")).sendKeys("My comment"); //populate the comments field by id.
//leave the webview to go back to native app.
remoteWebDriver.switchTo().window("NATIVE_APP");
//close the app.
remoteWebDriver.quit();
```

9
docs/en/index.md Normal file
View File

@@ -0,0 +1,9 @@
---
layout: default
title: Documentation
description: Appium v0.18.0 English Documentation
---
- Documentation
{% include doc_list.md url="/docs/en/0.18.0" %}

View File

@@ -1,9 +1,15 @@
---
title: Deploying your iOS app to your device
layout: default
---
Deploying your iOS app to your device
=====================================
To prepare for your Appium tests to run on a real device, you will need to:
1. Build your app with specific device-targeted parameters
1. Use [fruitstrap](https://github.com/ghughes/fruitstrap), a 3rd-party tool, to deploy this build to your device
1. Use [fruitstrap](https://github.com/ghughes/fruitstrap), a 3rd-party tool,
to deploy this build to your device
## Xcodebuild with parameters:
A newer xcodebuild now allows settings to be specified. Taken from [developer.apple.com](https://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man1/xcodebuild.1.html):
@@ -29,23 +35,39 @@ Specify "CODE_SIGN_IDENTITY" & "PROVISIONING_PROFILE" settings in the xcodebuild
```
xcodebuild -sdk <iphoneos> -target <target_name> -configuration <Debug> CODE_SIGN_IDENTITY="iPhone Developer: Mister Smith" PROVISIONING_PROFILE="XXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX"
```
On success, the app will be built to your ```<app_dir>/build/<configuration>-iphoneos/<app_name>.app```
## Deploy using Fruitstrap
Go clone a forked version of fruitstrap as the [ghughes version](https://github.com/ghughes/fruitstrap) is no longer maintained. Success has been confirmed with the [unprompted fork](https://github.com/unprompted/fruitstrap), but others are reportedly functional.
Once cloned, run ``make fruitstrap``
Now, copy the resulting ``fruitstrap`` executable to your app's project or a parent directory.
Go clone a forked version of fruitstrap as the [ghughes version](https://github.com/ghughes/fruitstrap)
is no longer maintained. Success has been confirmed with the [unprompted fork](https://github.com/unprompted/fruitstrap),
but others are reportedly functional.
Once cloned, run `make fruitstrap`
Now, copy the resulting `fruitstrap` executable to your app's project or a
parent directory.
Execute fruitstrap after a clean build by running (commands available depend
on your fork of fruitstrap):
Execute fruitstrap after a clean build by running (commands available depend on your fork of fruitstrap):
```
./fruitstrap -d -b <PATH_TO_APP> -i <Device_UDID>
```
If you are aiming to use continuous integration in this setup, you may find it useful to want to log the output of fruitstrap to both command line and log, like so:
If you are aiming to use continuous integration in this setup,
you may find it useful to want to log the output of fruitstrap to both
command line and log, like so:
```
./fruitstrap -d -b <PATH_TO_APP> -i <Device_UDID> 2>&1 | tee fruit.out
```
Since fruitstrap will need to be killed before the node server can be launched, an option is to scan the output of the fruitstrap launch for some telling sign that the app has completed launching. This may prove useful if you are doing this via a Rakefile and a ``go_device.sh`` script:
Since fruitstrap will need to be killed before the node server can be
launched, an option is to scan the output of the fruitstrap launch for some
telling sign that the app has completed launching. This may prove useful if
you are doing this via a Rakefile and a ``go_device.sh`` script:
```
bundle exec rake ci:fruit_deploy_app | while read line ; do
echo "$line" | grep "text to identify successful launch"
@@ -58,7 +80,8 @@ bundle exec rake ci:fruit_deploy_app | while read line ; do
fi
done
```
Once fruitstrap is killed, node server can be launched and Appium tests can run!
Next:
[Running Appium on Real Devices](https://github.com/appium/appium/wiki/Running-Appium-on-Real-Devices)
[Running Appium on Real Devices](./real-devices.html)

View File

@@ -1,13 +1,23 @@
---
title: Automating mobile web apps
layout: default
---
Automating mobile web apps
======================
If you're interested in automating your web app in Mobile Safari on iOS or Chrome on Android, Appium can help you. Basically, you write a normal WebDriver test, and use Appium as the Selenium server with a special set of desired capabilities.
If you're interested in automating your web app in Mobile Safari on iOS or
Chrome on Android, Appium can help you. Basically, you write a normal WebDriver
test, and use Appium as the Selenium server with a special set of desired
capabilities.
### Mobile Safari on Simulator
First of all, make sure developer mode is turned on in your Safari preferences so that the remote debugger port is open.
First of all, make sure developer mode is turned on in your Safari
preferences so that the remote debugger port is open.
If you are using the simulator or a real device, you MUST run Safari before attempting to use Appium.
If you are using the simulator or a real device, you MUST run Safari before
attempting to use Appium.
Then, use desired capabilities like these to run your test in mobile Safari:
@@ -21,15 +31,22 @@ Then, use desired capabilities like these to run your test in mobile Safari:
### Mobile Safari on a Real iOS Device
To be able to run your tests against mobile Safari we use the [SafariLauncher App](https://github.com/snevesbarros/SafariLauncher) to launch Safari. Once Safari has been launched the Remote Debugger automatically connects using the [ios-webkit-webkit-proxy](https://github.com/google/ios-webkit-debug-proxy).
To be able to run your tests against mobile Safari we use the [SafariLauncher
App](https://github.com/snevesbarros/SafariLauncher) to launch Safari. Once
Safari has been launched the Remote Debugger automatically connects using
the [ios-webkit-webkit-proxy](https://github.com/google/ios-webkit-debug-proxy).
<b>NOTE:</b> There is currently [a bug](https://github.com/google/ios-webkit-debug-proxy/issues/38) in the ios-webkit-debug-proxy. You have to trust the machine before you can run the ios-webkit-debug-proxy against your iOS device.
<b>NOTE:</b> There is currently [a bug](https://github
.com/google/ios-webkit-debug-proxy/issues/38) in the ios-webkit-debug-proxy.
You have to trust the machine before you can run the ios-webkit-debug-proxy
against your iOS device.
#### Setup
Before you can run your tests against Safari on a real device you will need to:
* Have the <b>ios-webkit-debug-proxy</b> installed and running (see the [hybrid docs](https://github.com/appium/appium/blob/master/docs/hybrid.md) for instructions)
* Turn on <b>web inspector</b> on iOS device (<b>settings > safari > advanced</b>, only for iOS 6.0 and up)
* Turn on <b>web inspector</b> on iOS device (<b>settings > safari >
advanced</b>, only for iOS 6.0 and up)
* Create a <b>provisioning profile</b> that can be used to deploy the SafariLauncherApp.
To create a profile for the launcher go into the <b>Apple Developers Member Center</b> and:
@@ -41,6 +58,7 @@ To create a profile for the launcher go into the <b>Apple Developers Member Cent
* <b>Step 6:</b> Search for the <b>UUID</b> and the string for it is your <b>identity code</b>.
Now that you have a profile open a terminal and run the following commands:
```bash
$ git clone https://github.com/appium/appium.git
$ cd appium
@@ -59,9 +77,11 @@ $ node /lib/server/main.js -U <UDID>
```
#### Running your test
To configure you test to run against safari simpley set the <b>"app"</b> to be <b>"safari"</b>.
##### Java Example
```java
//setup the web driver and launch the webview app.
DesiredCapabilities desiredCapabilities = new DesiredCapabilities();
@@ -93,4 +113,4 @@ Then, use desired capabilities like these to run your test in Chrome:
app: 'chrome'
, device: 'Android'
};
```
```

View File

@@ -1,3 +1,8 @@
---
title: Cross platform mobile methods
layout: default
---
#### Cross platform mobile methods
##### Reset
@@ -5,11 +10,13 @@
Mobile reset will reset the app's state.
Ruby + [appium_lib gem](https://github.com/appium/ruby_lib)
```ruby
mobile :reset
```
Ruby without the gem
```ruby
@driver.execute_script 'mobile: reset'
```
@@ -20,15 +27,16 @@ Fetch a file from the device's filesystem, returning it base64 encoded.
Takes a single argument, `path`. On Android and iOS, this is either the path to the file (relative to the root of the app's file system). On iOS only, if path starts with `/AppName.app`, which will be replaced with the application's .app directory
```
```ruby
# Android and iOS
'mobile: pullFile', {path: '/Library/AddressBook/AddressBook.sqlitedb'} #=> /Library/AddressBook/AddressBook.sqlitedb
@driver.execute_script 'mobile: pullFile', {path: '/Library/AddressBook/AddressBook.sqlitedb'} #=> /Library/AddressBook/AddressBook.sqlitedb
#iOS only
'mobile: pullFile, {path: '/UICatalog.app/logfile.log'} #=> /Applications/12323-452262-24241-23-124124/UICatalog.app/logfile.log
@driver.execute_script 'mobile: pullFile, {path: '/UICatalog.app/logfile.log'} #=> /Applications/12323-452262-24241-23-124124/UICatalog.app/logfile.log
```
Ruby
```ruby
@driver.execute_script('mobile: pullFile', {path: '/Library/AddressBook/AddressBook.sqlitedb'})
```
@@ -54,6 +62,7 @@ mobile :keyevent, keycode: 82
```
Ruby without the gem
```ruby
@driver.execute_script 'mobile: keyevent', :keycode => 82
```
@@ -68,4 +77,4 @@ Ruby + [appium_lib gem](https://github.com/appium/ruby_lib)
```ruby
scroll_to 'Gallery'
```
```

View File

@@ -1,3 +1,8 @@
---
title: Appium on real devices
layout: default
---
Appium on real iOS devices
======================
Appium has support for real device testing.

View File

@@ -1,17 +1,29 @@
---
title: Running Appium on Linux
layout: default
---
Running Appium on Linux
=======================
# Limitations
If you are running Appium on Linux, you cannot use the prebuilt '.app', which is built for OS X only. Additionally, you will not be able to test iOS apps because Appium relies on OS X-only libraries to support iOS testing.
If you are running Appium on Linux, you cannot use the prebuilt '.app',
which is built for OS X only. Additionally, you will not be able to test iOS
apps because Appium relies on OS X-only libraries to support iOS testing.
# Setup
To get started, you'll need to install node.js (v.0.8 or greater). Just follow the [instructions for your flavor of linux](https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager).
To get started, you'll need to install node.js (v.0.8 or greater). Just
follow the [instructions for your flavor of linux](https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager).
Once you've got node.js installed, install the [Android SDK](http://developer.android.com/sdk/index.html). You will need to run the 'android' tool (included in the SDK) and make sure you have an API Level 17 or greater API installed. You will also need Ant to build the bootstrap jar that Appium uses for testing Android.
Once you've got node.js installed, install the [Android SDK](http://developer.android.com/sdk/index.html).
You will need to run the 'android' tool (included in the SDK) and make sure
you have an API Level 17 or greater API installed. You will also need Ant to
build the bootstrap jar that Appium uses for testing Android.
Finally, set `$ANDROID_HOME` to be your Android SDK path. If you unzipped the Android SDK to /usr/local/adt/, for example, you should add this to your shell startup:
Finally, set `$ANDROID_HOME` to be your Android SDK path. If you unzipped the
Android SDK to /usr/local/adt/, for example, you should add this to your shell startup:
export ANDROID_HOME="/usr/local/adt/sdk"
@@ -19,7 +31,8 @@ Now that you're setup to run Appium, run `./reset.sh --android` from your Appium
# Running Appium
To run tests on Linux, you will need to have the Android Emulator booted and running an AVD with API Level 17 or greater. Then run Appium on the command line using node.js:
To run tests on Linux, you will need to have the Android Emulator booted and
running an AVD with API Level 17 or greater. Then run Appium on the command line using node.js:
node .
@@ -29,4 +42,4 @@ See the [server documentation](https://github.com/appium/appium/blob/master/docs
* There exists a hardware accelerated emulator for android, it has it's own
limitations. For more information you can check out this
[page](https://github.com/appium/appium/blob/master/docs/android-hax-emulator.md).
* Make sure that `hw.battery=yes` in your AVD's `config.ini`.
* Make sure that `hw.battery=yes` in your AVD's `config.ini`.

View File

@@ -1,4 +1,9 @@
Running Appium on Mac OS X
---
title: Running Appium on Mac OS X
layout: default
---
Running Appium on Mac OS X
=======
Appium on OS X supports iOS and Android testing.

View File

@@ -0,0 +1,60 @@
---
title: Running Appium on Windows
layout: default
---
Running Appium on Windows
=======================
# Limitations
If you are running Appium on Windows, you cannot use the prebuilt '.app',
which is built for OS X only. Additionally, you will not be able to test iOS
apps because Appium relies on OS X-only libraries to support iOS testing.
# Setup
To get started:
1. Install [node.js](http://nodejs.org/download/) (v.0.8 or greater). Use the
installer from nodejs.org.
1. Install the [Android SDK](http://developer.android.com/sdk/index.html).
You will need to run the 'android' tool (included in the SDK) and make sure
you have an API Level 17 or greater API installed. Set `ANDROID_HOME` to be
your Android SDK path and add the tools and platform-tools folders to your
PATH variable.
1. Install the Java JDK and set `JAVA_HOME` to your JDK folder.
1. Install [Apache Ant](http://ant.apache.org/bindownload.cgi) or use the one
that comes with the Android Windows SDK in the eclipse\plugins folder. Be
sure to add the folder containing ant to your PATH variable.
1. Install [Apache Maven](http://maven.apache.org/download.cgi) and set the
M2HOME and M2 environment variables. Set M2HOME to the directory maven is
installed in, and set M2 to %M2HOME\bin. Add the path you used for M2 to
your PATH.
1. Install [Git](http://git-scm.com/download/win) Be sure to install Git for
windows to run in the regular command prompt.
1. Instal [cURL](http://curl.haxx.se/download.html)
Now that you've downloaded everything, run:
reset.bat
# Running Appium
To run tests on Windows, you will need to have the Android Emulator booted or
an Android Device connected that is running an AVD with API Level 17 or
greater. Then run Appium on the command line using node.js:
node .
See the [server documentation](https://github.com/appium/appium/blob/master/docs/server-args.md)
for all the command line arguments.
# Notes
* you must supply the --no-reset and --full-reset flags currently for android
to work on Windows.
* There exists a hardware accelerated emulator for android, it has it's own
limitations. For more information you can check out this
[page](https://github.com/appium/appium/blob/master/docs/android-hax-emulator.md).
* Make sure that `hw.battery=yes` in your AVD's `config.ini`.

View File

@@ -1,8 +1,14 @@
---
title: Running Tests
layout: default
---
Running Tests
=============
<a name="prep-ios"></a>Preparing your app for test (iOS)
-----
Test apps run on the simulator have to be compiled specifically for the
simulator, for example by executing the following command in the Xcode project:
@@ -17,11 +23,13 @@ unpack it for you. Nice if you're not using Appium locally.
<a name="prep-android"></a>Preparing your app for test (Android)
------
Nothing in particular needs to be done to run your .apk using Appium. If you
want to zip it up, you can.
<a name="run-ios"></a>Running your test app with Appium (iOS)
------
The best way to see what to do currently is to look at the example tests:
[Node.js](https://github.com/appium/appium/tree/master/sample-code/examples/node) | [Python](https://github.com/appium/appium/tree/master/sample-code/examples/python) | [PHP](https://github.com/appium/appium/tree/master/sample-code/examples/php) | [Ruby](https://github.com/appium/appium/tree/master/sample-code/examples/ruby) | [Java](https://github.com/appium/appium/tree/master/sample-code/examples/java)
@@ -53,6 +61,7 @@ all set now!
<a name="run-android"></a>Running your test app with Appium (Android)
-----
First, make sure you have one and only one Android emulator or device
connected. If you run `adb devices`, for example, you should see one device
connected. This is the device Appium will use for tests. Of course, to have
@@ -106,13 +115,13 @@ all set now!
<a name="run-selendroid"></a>Running your test app with Appium (Android devices &lt; 4.2, and hybrid tests)
-----
Android devices before version 4.2 (API Level 17) do not have Google's
[UiAutomator
framework](developer.android.com/tools/help/uiautomator/index.html) installed.
This is what Appium uses to perform the
automation behaviors on the device. For earlier devices or tests of hybrid
(webview-based) apps, Appium comes bundled with another automation backend
called [Selendroid](http://selendroid.io/).
[UiAutomator framework](developer.android.com/tools/help/uiautomator/index.html)
installed. This is what Appium uses to perform the automation behaviors on
the device. For earlier devices or tests of hybrid (webview-based) apps,
Appium comes bundled with another automation backend called [Selendroid]
(http://selendroid.io/).
To use Selendroid, all that is required is to slightly change the set of
desired capabilities mentioned above, by replacing 'Android' with 'Selendroid':

View File

@@ -1,3 +1,8 @@
---
title: Appium server arguments
layout: default
---
Appium server arguments
==========
@@ -66,4 +71,4 @@ All flags are optional, but some are required in conjunction with certain others
|`--key-password`|android|(Android-only) Key password||
|`--show-config`|false|Show info about the appium server configuration and exit||
|`--command-timeout`|60|The default command timeout for the server to use for all sessions. Will still be overridden by newCommandTimeout cap||
|`--keep-keychains`|false|(iOS) Whether to keep keychains (Library/Keychains) when reset app between sessions||
|`--keep-keychains`|false|(iOS) Whether to keep keychains (Library/Keychains) when reset app between sessions||

View File

@@ -1,19 +1,36 @@
---
title: Style guide for contributors
layout: default
---
Style guide for contributors
============================
Thanks for your contribution to Appium! Here are the principles we use when writing javascript. Please conform to these so we can merge your pull request without going back and forth about style. The main principle is: *make your code look like the surrounding code*.
Thanks for your contribution to Appium! Here are the principles we use when
writing javascript. Please conform to these so we can merge your pull request
without going back and forth about style. The main principle is: *make your
code look like the surrounding code*.
Rebasing
--------
Commits in a pull request should consist of [logical changes](https://github.com/appium/appium/pull/920#issuecomment-21588553). If there are multiple authors, make sure each author has their own commit. It's not a good idea to modify author information.
Merge commits should be rebased out of pull requests.
Commits in a pull request should consist of [logical changes](https://github.com/appium/appium/pull/920#issuecomment-21588553).
If there are multiple authors, make sure each author has their own commit.
It's not a good idea to modify author information. Merge commits should be
rebased out of pull requests.
Linting
-------
All code (except for code in `bootstrap.js` which uses proprietary Apple methods) must pass JSLint. To check your code, you can simply run `grunt lint` from the Appium repo dir. If you've created a new .js file, please make sure it is covered by the wildcards in `grunt.js` or that it is added specifically.
All code (except for code in `bootstrap.js` which uses proprietary Apple
methods) must pass JSLint. To check your code, you can simply run `grunt
lint` from the Appium repo dir. If you've created a new .js file,
please make sure it is covered by the wildcards in `grunt.js` or that it is
added specifically.
It's easy to have your code linted as you type, which makes the whole process much smoother. We like [jshint](http://www.jshint.com), which has integrations with a lot of source code editors. The file `.jshintrc` is checked into the repo, and its contents are:
It's easy to have your code linted as you type, which makes the whole process
much smoother. We like [jshint](http://www.jshint.com),
which has integrations with a lot of source code editors. The file `
.jshintrc` is checked into the repo, and its contents are:
```json
{
@@ -29,7 +46,10 @@ It's easy to have your code linted as you type, which makes the whole process mu
}
```
These defined what we want to see warnings about, etc..., while we're editing. See [this page](http://www.jshint.com/platforms/) for the list of editors and platforms and how to get your editor set up with automatic linting.
These defined what we want to see warnings about, etc...,
while we're editing. See [this page](http://www.jshint.com/platforms/) for
the list of editors and platforms and how to get your editor set up with
automatic linting.
Style notes
------
@@ -228,4 +248,4 @@ h.driver
.execute("'nan'--")
.should.be.rejectedWith("status: 13")
.nodeify(done);
```
```

View File

@@ -1,5 +1,9 @@
# Touch Actions
---
title: Touch Actions
layout: default
---
# Touch Actions
WebDriver provides an API to send some kinds of touch gestures to the devices,
for example, to long press an element you can do:
@@ -14,6 +18,7 @@ new TouchActions(driver).longPress(imageView).perform();
For Android Application:
Java:
```java
WebElement element = wd.findElement(By.name("API Demo"));
JavascriptExecutor js = (JavascriptExecutor) wd;
@@ -23,6 +28,7 @@ js.executeScript("mobile: longClick", tapObject);
```
Python:
```python
element = wd.find_element_by_xpath("your_element_xpath")
wd.execute_script("mobile: longClick",{ "touchCount": 1, "x": 0, "y": 300, "element":element.id })
@@ -35,6 +41,4 @@ Currently Appium support some of the gestures in the Touch Actions API:
* single tap
Some other gestures are supported through the "Alternative access method"
explained in [Automating mobile gestures](gestures.md)
explained in [Automating mobile gestures](gestures.md)

View File

@@ -1,12 +1,20 @@
---
title: Troubleshooting Appium
layout: default
---
Troubleshooting Appium
======================
Here's what to do if you're experiencing problems, before you submit a ticket
to github or write to the appium-discuss mailing list.
## General
* Make sure you've followed the getting started steps in the [README](https://github.com/appium/appium/blob/master/README.md)
* Make sure your system is set up appropriately (i.e., XCode is updated, Android SDK is installed and `ANDROID_HOME` is set: [setup instructions](https://github.com/appium/appium/blob/master/docs/running-on-osx.md))
* Make sure your system is set up appropriately (i.e., XCode is updated,
Android SDK is installed and `ANDROID_HOME` is set:
[setup instructions](https://github.com/appium/appium/blob/master/docs/running-on-osx.md))
* Make sure the paths to your applications are correct
## If you're running Appium.app
@@ -17,42 +25,58 @@ to github or write to the appium-discuss mailing list.
## If you're running Appium from source
* `git pull` to make sure you're running the latest code
* Run the appropriate flavor of `reset.sh` based on what you're trying to automate:
* Run the appropriate flavor of `reset.sh` based on what you're trying to
automate:
./reset.sh # all
./reset.sh --ios # ios-only
./reset.sh --android # android-only
./reset.sh --selendroid # selendroid-only
* You might also want to run `reset.sh` with the `--dev` flag if you want the test apps downloaded and built as well.
* You can also use `appium-doctor` to automatically verify that all dependencies are met. If running from source, you
may have to use `bin/appium-doctor.js` or `node bin/appium-doctor.js`.
* You might also want to run `reset.sh` with the `--dev` flag if you want the
test apps downloaded and built as well.
* You can also use `appium-doctor` to automatically verify that all
dependencies are met. If running from source, you may have to use
`bin/appium-doctor.js` or `node bin/appium-doctor.js`.
* If you get this error after upgrading to Android SDK 22:
`{ANDROID_HOME}/tools/ant/uibuild.xml:155: SDK does not have any Build Tools installed.`
In the Android SDK 22, the platform and build tools are split up into their own items in the SDK manager. Make sure you install the build-tools and platform-tools.
`{ANDROID_HOME}/tools/ant/uibuild.xml:155: SDK does not have any Build Tools installed.`
In the Android SDK 22, the platform and build tools are split up into their
own items in the SDK manager. Make sure you install the build-tools and platform-tools.
## Android
* Make sure the Android emulator is up and running.
* It's sometimes useful to run `adb kill-server && adb devices`. This can reset the connection to the Android device.
* Make sure you know about the `app-package`, `app-activity`, and `app-wait-activity` desiredCapabilities (see [this doc](https://github.com/appium/appium/blob/master/docs/running-tests.md#run-android) for more information).
* It's sometimes useful to run `adb kill-server && adb devices`. This can
reset the connection to the Android device.
* Make sure you know about the `app-package`, `app-activity`,
and `app-wait-activity` desiredCapabilities (see [this doc](https://github.com/appium/appium/blob/master/docs/running-tests.md#run-android)
for more information).
* Make sure you set ANDROID_HOME pointing to the Android SDK directory
## IOS
* Make sure Instruments.app is not open
* If you're running the simulator, make sure your actual device is not plugged in
* If you're running the simulator, make sure your actual device is not
plugged in
* Make sure the accessibility helper is turned off in your Settings app
* Make sure the app is compiled for the version of the simulator that's being run
* If you've ever run Appium with sudo, you might need to `sudo rm /tmp/instruments_sock` and try again as not-sudo.
* If this is the first time you've run Appium, make sure to authorize the use of Instruments. Usually a box will pop up that you enter your password into. If you're running Appium from source, you can simply run `sudo grunt authorize` from the main repo to avoid getting this popup. If you're running from npm, run `sudo authorize_ios` instead.
* If you see `iOS Simulator failed to install the application.` and the paths are correct, try restarting the computer.
* Make sure the app is compiled for the version of the simulator that's being
run
* If you've ever run Appium with sudo, you might need to `sudo rm
/tmp/instruments_sock` and try again as not-sudo.
* If this is the first time you've run Appium, make sure to authorize the use
of Instruments. Usually a box will pop up that you enter your password into
. If you're running Appium from source, you can simply run `sudo grunt authorize`
from the main repo to avoid getting this popup. If you're running from npm,
run `sudo authorize_ios` instead.
* If you see `iOS Simulator failed to install the application.` and the
paths are correct, try restarting the computer.
## Webview/Hybrid/Safari app support
* Make Sure you enable the 'Web Inspector' on the real device.
* Make Sure you enable the Safari - Advance Preferences- Developer menu for simulators.
* If you getting this error: select_port() failed, when trying to open the proxy, see this [discussion](https://groups.google.com/forum/#!topic/appium-discuss/tw2GaSN8WX0)
* Make Sure you enable the Safari - Advance Preferences- Developer menu for
simulators.
* If you getting this error: select_port() failed, when trying to open the
proxy, see this [discussion](https://groups.google.com/forum/#!topic/appium-discuss/tw2GaSN8WX0)
## FirefoxOS
@@ -61,15 +85,22 @@ In the Android SDK 22, the platform and build tools are split up into their own
## Let the community know
Once you've tried the above steps and your issue still isn't resolved, here's what you can do:
Once you've tried the above steps and your issue still isn't resolved,
here's what you can do:
If you've found what you believe is a bug, go straight to the [issue tracker](https://github.com/appium/appium/issues) and submit an issue describing the bug and a repro case.
If you've found what you believe is a bug, go straight to the [issue tracker](https://github.com/appium/appium/issues)
and submit an issue describing the bug and a repro case.
If you're having trouble getting Appium working and the error messages Appium provides are not clear, join the [mailing list](https://groups.google.com/d/forum/appium-discuss) and send a message. Please include the following:
If you're having trouble getting Appium working and the error messages Appium
provides are not clear, join the [mailing list](https://groups.google.com/d/forum/appium-discuss)
and send a message. Please include the following:
* How you're running Appium (Appium.app, npm, source)
* The client-side and server-side errors you're getting (i.e., "In Python this is the exception I get in my test script, and here's a link to a paste of the Appium server output)
* Per above, it's very important to include a paste of the Appium server output when it's run in verbose mode so that we can diagnose what's going on.
* The client-side and server-side errors you're getting (i.e.,
"In Python this is the exception I get in my test script,
and here's a link to a paste of the Appium server output)
* Per above, it's very important to include a paste of the Appium server
output when it's run in verbose mode so that we can diagnose what's going on.
## Known Issues
@@ -80,10 +111,13 @@ If you're having trouble getting Appium working and the error messages Appium pr
found. This results in an error that looks like `(null) cannot be tapped`.
Sometimes the only solution is to put the finding-and-acting code in a retry
block. See also `mobile: findAndAct` on the [finding elements doc page](https://github.com/appium/appium/blob/master/docs/finding-elements.md)
* Appium may have difficulties finding the `node` executable if you've installed Node and npm via MacPorts. You must make sure that the MacPorts bin folder (`/opt/local/bin` by default) is added to `PATH` somewhere in your `~/.profile`, `~/.bash_profile` or `~/.bashrc`.
* Appium may have difficulties finding the `node` executable if you've
installed Node and npm via MacPorts. You must make sure that the MacPorts bin
folder (`/opt/local/bin` by default) is added to `PATH` somewhere in your
`~/.profile`, `~/.bash_profile` or `~/.bashrc`.
## Specific Errors
|Action|Error|Resolution|
|------|-----|----------|
|Running reset.sh|xcodebuild: error: SDK "iphonesimulator6.1" cannot be located|Install the iPhone 6.1 SDK _or_ build the test apps with a separate SDK, e.g., `grunt buildApp:UICatalog:iphonesimulator5.1`|
|Running reset.sh|xcodebuild: error: SDK "iphonesimulator6.1" cannot be located|Install the iPhone 6.1 SDK _or_ build the test apps with a separate SDK, e.g., `grunt buildApp:UICatalog:iphonesimulator5.1`|

View File

@@ -1,330 +0,0 @@
Automating mobile gestures
==========================
While the Selenium WebDriver spec has support for certain kinds of mobile interaction, its parameters are not always easily mappable to the functionality that the underlying device automation (like UIAutomation in the case of iOS) provides. To that end, Appium augments the WebDriver spec with extra commands and parameters for mobile gestures:
* **tap** (on screen or on element) with options:
* how many fingers
* how long to tap
* how many taps
* where precisely to tap on the screen or element
* **flick** (on screen or on element) with options:
* how many fingers
* where to start the flick on screen or element
* where to end the flick on screen or element
* **swipe/drag** (on screen or on element) with options:
* how many fingers
* how long the swipe/drag takes in seconds
* where to start the swipe on screen or element
* where to end the swipe on screen or element
* **scroll to** (element)
* **slider**
* **shake**
* **longTap** (element)
* set the **orientation** with option:
* new orientation (landscape or portrait)
## JSON Wire Protocol server extensions
Here are the endpoints with which we have implemented these additions to the spec.
**Note on coordinates:** All the X and Y parameters listed below can be used in two ways. If they are between 0 and 1 (e.g., 0.5), they are taken to be percentage of screen or element size. In other words, `{x: 0.5, y: 0.25}` means a coordinate that is 50% from the left side of the screen/element, and 25% from the top of the screen/element. If the values are greater than 1, they are taken as pixels. So, `{x: 100, y: 300}` means a coordinate that is 100 pixels from the left and 300 from the top of the screen/element.
**Note on performing actions on screen vs elements:** These methods all take an optional `element` parameter. If present, this is taken to be the ID of an element which has already been retrieved. So in this case, the coordinates will be taken to refer to the rectangle of that element only. So `{x: 0.5, y: 0.5, element: '3'}` means "the exact middle point of the element with ID '3'".
* `POST session/:sessionId/touch/tap` - perform a tap on the screen or an element
* URL Parameter: sessionId of session to route to
* JSON parameters:
* `tapCount` (optional, default `1`): how many times to tap
* `touchCount` (optional, default `1`): how many fingers to tap with
* `duration` (optional, default `0.1`): how long (in seconds) to tap
* `x` (optional, default `0.5`): x coordinate to tap (in pixels or relative units)
* `y` (optional, default `0.5`): y coordinate to tap (in pixels or relative units)
* `element` (optional): ID of element to scope this command to
* `POST session:/sessionId/touch/flick_precise` - perform a flick on the screen or an element
* URL Parameter: sessionId of session to route to
* JSON parameters:
* `touchCount` (optional, default `1`): how many fingers to flick with
* `startX` (optional, default `0.5`): x coordinate where flick begins (in pixels or relative units)
* `startY` (optional, default `0.5`): y coordinate where flick begins (in pixels or relative units)
* `endX` (required): x coordinate where flick ends (in pixels or relative units)
* `endY` (required): y coordinate where flick ends (in pixels or relative units)
* `element` (optional): ID of element to scope this command to
* `POST session:/sessionId/touch/swipe` - perform a swipe/drag on the screen or an element
* URL Parameter: sessionId of session to route to
* JSON parameters:
* `touchCount` (optional, default `1`): how many fingers to flick with
* `startX` (optional, default `0.5`): x coordinate where swipe begins (in pixels or relative units)
* `startY` (optional, default `0.5`): y coordinate where swipe begins (in pixels or relative units)
* `endX` (required): x coordinate where swipe ends (in pixels or relative units)
* `endY` (required): y coordinate where swipe ends (in pixels or relative units)
* `duration` (optional, default `0.8`): time (in seconds) to spend performing the swipe/drag
* `element` (optional): ID of element to scope this command to
**Note on setting orientation:** Setting the orientation takes different parameters than the tap, flick, and swipe methods. This action is performed by setting the orientation of the browser to "LANDSCAPE" or "PORTRAIT". The alternative access method below does not apply to setting orientation.
* `POST /session/:sessionId/orientation` - set the orientation of the browser
* URL Parameter: sessionId of session to route to
* JSON parameters:
* `orientation` (required): new orientation, either "LANDSCAPE" or "PORTRAIT"
## Alternative access method
Extending the JSON Wire Protocol is great, but it means that the various WebDriver language bindings will have to implement access to these endpoints in their own way. Naturally, this will take different amounts of time depending on the project. We have instituted a way to get around this delay, by using `driver.execute()` with special parameters.
`POST session/:sessionId/execute` takes two JSON parameters:
* `script` (usually a snippet of javascript)
* `args` (usually an array of arguments passed to that snippet in the javascript engine)
In the case of these new mobile methods, `script` must be one of:
* `mobile: tap`
* `mobile: flick`
* `mobile: swipe`
* `mobile: scrollTo`
* `mobile: scroll`
* `mobile: shake`
(The `mobile:` prefix allows us to route these requests to the appropriate endpoint).
And `args` will be an array with one element: a Javascript object defining the parameters for the corresponding function. So, let's say I want to call `tap` on a certain screen position. I can do so by calling `driver.execute` with these JSON parameters:
```json
{
"script": "mobile: tap",
"args": [{
"x": 0.8,
"y": 0.4
}]
}
```
In this example, our new `tap` method will be called with the `x` and `y` params as described above.
## Code examples
In these examples, note that the element parameter is always optional.
### Tap
* **WD.js:**
```js
driver.elementsByTagName('tableCell', function(err, els) {
var tapOpts = {
x: 150 // in pixels from left
, y: 30 // in pixels from top
, element: els[4].value // the id of the element we want to tap
};
driver.execute("mobile: tap", [tapOpts], function(err) {
// continue testing
});
});
```
* **Java:**
```java
WebElement row = driver.findElements(By.tagName("tableCell")).get(4);
JavascriptExecutor js = (JavascriptExecutor) driver;
HashMap<String, Double> tapObject = new HashMap<String, Double>();
tapObject.put("x", 150); // in pixels from left
tapObject.put("y", 30); // in pixels from top
tapObject.put("element", ((RemoteWebElement) row).getId()); // the id of the element we want to tap
js.executeScript("mobile: tap", tapObject);
```
```java
//In iOS app, if UI element visbile property is "false".
//Using element location tap on it.
WebElement element = wd.findElement(By.xpath("//window[1]/scrollview[1]/image[1]"));
JavascriptExecutor js = (JavascriptExecutor) wd;
HashMap<String, Double> tapObject = new HashMap<String, Double>();
tapObject.put("x", (double) element.getLocation().getX());
tapObject.put("y", (double) element.getLocation().getY());
tapObject.put("duration", 0.1);
js.executeScript("mobile: tap", tapObject);
```
* **Python:**
```python
driver.execute_script("mobile: tap", {"touchCount":"1", "x":"0.9", "y":"0.8", "element":element.id})
```
* **Ruby:**
```ruby
@driver.execute_script 'mobile: tap', :x => 150, :y => 30
```
* **Ruby:**
```ruby
b = @driver.find_element :name, 'Sign In'
@driver.execute_script 'mobile: tap', :element => b.ref
```
* **C#:**
```C#
Dictionary<String, Double> coords = new Dictionary<string, double>();
coords.Add("x", 12);
coords.Add("y", 12);
driver.ExecuteScript("mobile: tap", coords);
```
### Flick
* **WD.js:**
```js
// options for a 2-finger flick from the center of the screen to the top left
var flickOpts = {
endX: 0
, endY: 0
, touchCount: 2
};
driver.execute("mobile: flick", [flickOpts], function(err) {
// continue testing
});
```
* **Java:**
```java
JavascriptExecutor js = (JavascriptExecutor) driver;
HashMap<String, Double> flickObject = new HashMap<String, Double>();
flickObject.put("endX", 0);
flickObject.put("endY", 0);
flickObject.put("touchCount", 2);
js.executeScript("mobile: flick", flickObject);
```
### Swipe
*Note*: Swiping is unfortunately broken in iOS7, because of a bug in Apple's
frameworks. For iOS7, see `mobile: scroll` as a workaround that works for most
cases.
* **WD.js:**
```js
// options for a slow swipe from the right edge of the screen to the left
var swipeOpts = {
startX: 0.95
, startY: 0.5
, endX: 0.05
, endY: 0.5
, duration: 1.8
};
driver.execute("mobile: swipe", [swipeOpts], function(err) {
// continue testing
});
```
* **Java:**
```java
JavascriptExecutor js = (JavascriptExecutor) driver;
HashMap<String, Double> swipeObject = new HashMap<String, Double>();
swipeObject.put("startX", 0.95);
swipeObject.put("startY", 0.5);
swipeObject.put("endX", 0.05);
swipeObject.put("endY", 0.5);
swipeObject.put("duration", 1.8);
js.executeScript("mobile: swipe", swipeObject);
```
### Scroll
* **WD.js:**
```js
// scroll the view down
driver.execute("mobile: scroll", [{direction: 'down'}], function(err) {
// continue testing
});
```
* **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);
```
### Slider
**iOS**
* **Java**
```java
// slider values can be string representations of numbers between 0 and 1
// e.g., "0.1" is 10%, "1.0" is 100%
WebElement slider = wd.findElement(By.xpath("//window[1]/slider[1]"));
slider.sendKeys("0.1");
```
**Android**
The best way to interact with the slider on Android is with the 'mobile: tap' gesture. It is difficult to find a reliable way to set a specific percentage that works on all screen sizes, however. Therefore, it is recommended to write tests that focus on minimum, 50%, and maximum.
* **Ruby**
```Ruby
# 0%
@driver.execute_script 'mobile: tap', :x =>slider.location.x, :y =>slider.location.y
# 100%
@driver.execute_script 'mobile: tap', :x =>slider.location.x + slider.size.width - 1, :y =>slider.location.y
# 50%
slider.click
```
### Set orientation
* **WD.js:**
```js
driver.setOrientation("LANDSCAPE", function(err) {
// continue testing
});
```
* **Python:**
```python
driver.orientation = "LANDSCAPE"
```
### Scroll To
```ruby
b = @driver.find_element :name, 'Sign In'
@driver.execute_script 'mobile: scrollTo', :element => b.ref
```
```Java
JavascriptExecutor js = (JavascriptExecutor) driver;
WebElement element = wd.findElement(By.name("Log In"));;
HashMap<String, String> scrollToObject = new HashMap<String, String>();
scrollToObject.put("element",((RemoteWebElement) element).getId());
js.executeScript("mobile: scrollTo", scrollToObject);
```
### longTap
* **c#**
```c#
// long tap an element
//
Dictionary<string, object> parameters = new Dictionary<string, object>();
parameters.Add("using", _attributeType);
parameters.Add("value", _attribute);
Response response = rm.executescript(DriverCommand.FindElement, parameters);
Dictionary<string, object> elementDictionary = response.Value as Dictionary<string, object>;
string id = null;
if (elementDictionary != null)
{
id = (string)elementDictionary["ELEMENT"];
}
IJavaScriptExecutor js = (IJavaScriptExecutor)remoteDriver;
Dictionary<String, String> longTapObject = new Dictionary<String, String>();
longTapObject.Add("element", id);
js.ExecuteScript("mobile: longClick", longTapObject);
```

View File

@@ -1,37 +0,0 @@
Running Appium on Windows
=======================
# Limitations
If you are running Appium on Windows, you cannot use the prebuilt '.app', which is built for OS X only. Additionally, you will not be able to test iOS apps because Appium relies on OS X-only libraries to support iOS testing.
# Setup
To get started:
1. Install [node.js](http://nodejs.org/download/) (v.0.8 or greater). Use the installer from nodejs.org.
2. Install the [Android SDK](http://developer.android.com/sdk/index.html). You will need to run the 'android' tool (included in the SDK) and make sure you have an API Level 17 or greater API installed. Set `ANDROID_HOME` to be your Android SDK path and add the tools and platform-tools folders to your PATH variable.
3. Install the Java JDK and set `JAVA_HOME` to your JDK folder.
4. Install [Apache Ant](http://ant.apache.org/bindownload.cgi) or use the one that comes with the Android Windows SDK in the eclipse\plugins folder. Be sure to add the folder containing ant to your PATH variable.
5. Install [Apache Maven](http://maven.apache.org/download.cgi) and set the M2HOME and M2 environment variables. Set M2HOME to the directory maven is installed in, and set M2 to %M2HOME\bin. Add the path you used for M2 to your PATH.
6. Install [Git](http://git-scm.com/download/win) Be sure to install Git for windows to run in the regular command prompt.
7. Instal [cURL](http://curl.haxx.se/download.html)
Now that you've downloaded everything, run:
reset.bat
# Running Appium
To run tests on Windows, you will need to have the Android Emulator booted or an Android Device connected that is running an AVD with API Level 17 or greater. Then run Appium on the command line using node.js:
node .
See the [server documentation](https://github.com/appium/appium/blob/master/docs/server-args.md) for all the command line arguments.
# Notes
* you must supply the --no-reset and --full-reset flags currently for android to work on Windows.
* There exists a hardware accelerated emulator for android, it has it's own
limitations. For more information you can check out this
[page](https://github.com/appium/appium/blob/master/docs/android-hax-emulator.md).
* Make sure that `hw.battery=yes` in your AVD's `config.ini`.