mirror of
https://github.com/appium/appium.git
synced 2026-05-21 19:38:52 -05:00
@@ -10,6 +10,10 @@ instrumentation class.
|
||||
caps = { androidCoverage: 'com.example.pkg/com.example.pkg.instrumentation.MyInstrumentation' }
|
||||
```
|
||||
|
||||
```python
|
||||
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`
|
||||
@@ -21,6 +25,10 @@ the coverage.ec file from the device.
|
||||
mobile :endCoverage, intent: 'com.example.pkg.END_EMMA', path: '/mnt/sdcard/coverage.ec'
|
||||
```
|
||||
|
||||
```python
|
||||
driver.end_test_coverage(intent='com.example.pkg.END_EMMA', path='/mnt/sdcard/coverage.ec')
|
||||
```
|
||||
|
||||
`AndroidManifest.xml` defines the instrumentation and broadcast receiver.
|
||||
|
||||
```xml
|
||||
@@ -28,7 +36,7 @@ mobile :endCoverage, intent: 'com.example.pkg.END_EMMA', path: '/mnt/sdcard/cove
|
||||
android:name="com.example.pkg.instrumentation.MyInstrumentation"
|
||||
android:targetPackage="com.example.pkg" >
|
||||
</instrumentation>
|
||||
|
||||
|
||||
<!-- adb shell am broadcast -a com.example.pkg.END_EMMA -->
|
||||
<receiver android:name="com.example.pkg.instrumentation.EndEmmaBroadcast" >
|
||||
<intent-filter>
|
||||
@@ -111,4 +119,4 @@ 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
|
||||
> 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
|
||||
|
||||
+25
-24
@@ -32,7 +32,7 @@ lock 5
|
||||
```
|
||||
|
||||
```python
|
||||
self.driver.lock(5)
|
||||
driver.lock(5)
|
||||
```
|
||||
|
||||
```java
|
||||
@@ -60,7 +60,7 @@ background_app 5
|
||||
```
|
||||
|
||||
```python
|
||||
self.driver.background_app(5)
|
||||
driver.background_app(5)
|
||||
```
|
||||
|
||||
```java
|
||||
@@ -88,7 +88,7 @@ hide_keyboard
|
||||
```
|
||||
|
||||
```python
|
||||
self.driver.hide_keyboard()
|
||||
driver.hide_keyboard()
|
||||
```
|
||||
|
||||
```java
|
||||
@@ -116,7 +116,7 @@ is_installed? "com.example.android.apis"
|
||||
```
|
||||
|
||||
```python
|
||||
self.driver.is_app_installed('com.example.android.apis')
|
||||
driver.is_app_installed('com.example.android.apis')
|
||||
```
|
||||
|
||||
```java
|
||||
@@ -144,7 +144,7 @@ install 'path/to/my.apk'
|
||||
```
|
||||
|
||||
```python
|
||||
self.driver.install_app('path/to/my.apk')
|
||||
driver.install_app('path/to/my.apk')
|
||||
```
|
||||
|
||||
```java
|
||||
@@ -172,7 +172,7 @@ remove 'com.example.android.apis'
|
||||
```
|
||||
|
||||
```python
|
||||
self.driver.remove_app('com.example.android.apis')
|
||||
driver.remove_app('com.example.android.apis')
|
||||
```
|
||||
|
||||
```java
|
||||
@@ -200,7 +200,7 @@ shake
|
||||
```
|
||||
|
||||
```python
|
||||
self.driver.shake()
|
||||
driver.shake()
|
||||
```
|
||||
|
||||
```java
|
||||
@@ -228,7 +228,7 @@ close_app
|
||||
```
|
||||
|
||||
```python
|
||||
self.driver.close_app();
|
||||
driver.close_app();
|
||||
```
|
||||
|
||||
```java
|
||||
@@ -256,7 +256,7 @@ launch
|
||||
```
|
||||
|
||||
```python
|
||||
self.driver.launch_app()
|
||||
driver.launch_app()
|
||||
```
|
||||
|
||||
```java
|
||||
@@ -284,7 +284,7 @@ reset
|
||||
```
|
||||
|
||||
```python
|
||||
self.driver.reset()
|
||||
driver.reset()
|
||||
```
|
||||
|
||||
```java
|
||||
@@ -312,7 +312,7 @@ context_array = available_contexts
|
||||
```
|
||||
|
||||
```python
|
||||
self.driver.contexts
|
||||
driver.contexts
|
||||
```
|
||||
|
||||
```java
|
||||
@@ -341,7 +341,7 @@ context = current_context
|
||||
```
|
||||
|
||||
```python
|
||||
self.driver.current_context
|
||||
driver.current_context
|
||||
```
|
||||
|
||||
```java
|
||||
@@ -369,7 +369,7 @@ switch_to_default_context
|
||||
```
|
||||
|
||||
```python
|
||||
self.driver.switch_to.context(None)
|
||||
driver.switch_to.context(None)
|
||||
```
|
||||
|
||||
```java
|
||||
@@ -397,7 +397,7 @@ strings = app_strings
|
||||
```
|
||||
|
||||
```python
|
||||
self.driver.app_strings
|
||||
driver.app_strings
|
||||
```
|
||||
|
||||
```java
|
||||
@@ -425,7 +425,7 @@ key_event 176
|
||||
```
|
||||
|
||||
```python
|
||||
self.driver.keyevent(176)
|
||||
driver.keyevent(176)
|
||||
```
|
||||
|
||||
```java
|
||||
@@ -453,7 +453,7 @@ current_activity
|
||||
```
|
||||
|
||||
```python
|
||||
self.driver.current_activity
|
||||
driver.current_activity
|
||||
```
|
||||
|
||||
```java
|
||||
@@ -484,7 +484,8 @@ touch_action.press(element: element, x: 10, y: 10).perform
|
||||
```
|
||||
|
||||
```python
|
||||
self._touch_action.tap(element, 10, 10)
|
||||
action = TouchAction(driver)
|
||||
action.press(element=el, x=10, y=10).release().perform()
|
||||
```
|
||||
|
||||
```java
|
||||
@@ -521,11 +522,11 @@ swipe start_x: 75, start_y: 500, end_x: 75, end_y: 0, duration: 0.8
|
||||
```
|
||||
|
||||
```python
|
||||
self.driver.swipe(75, 500, 75, 0, 0.8)
|
||||
driver.swipe(75, 500, 75, 0, 0.8)
|
||||
```
|
||||
|
||||
```java
|
||||
driver.swipe(75, 500, 75, 0, 800)
|
||||
driver.swipe(startx=75, starty=500, endx=75, endy=0, duration=800)
|
||||
```
|
||||
|
||||
```javascript
|
||||
@@ -549,7 +550,7 @@ pinch 75
|
||||
```
|
||||
|
||||
```python
|
||||
self.driver.pinch(element=el)
|
||||
driver.pinch(element=el)
|
||||
```
|
||||
|
||||
```java
|
||||
@@ -577,7 +578,7 @@ zoom 200
|
||||
```
|
||||
|
||||
```python
|
||||
self.driver.zoom(element=el)
|
||||
driver.zoom(element=el)
|
||||
```
|
||||
|
||||
```java
|
||||
@@ -605,7 +606,7 @@ pull_file 'Library/AddressBook/AddressBook.sqlitedb'
|
||||
```
|
||||
|
||||
```python
|
||||
self.driver.pull_file('Library/AddressBook/AddressBook.sqlitedb')
|
||||
driver.pull_file('Library/AddressBook/AddressBook.sqlitedb')
|
||||
```
|
||||
|
||||
```java
|
||||
@@ -637,7 +638,7 @@ push_file path, data
|
||||
```python
|
||||
data = "some data for the file"
|
||||
path = "/data/local/tmp/file.txt"
|
||||
self.driver.push_file(path, data.encode('base64'))
|
||||
driver.push_file(path, data.encode('base64'))
|
||||
```
|
||||
|
||||
```java
|
||||
@@ -665,4 +666,4 @@ Appium's desktop app supports OS X and Windows.
|
||||
- [Appium.app for OS X][bitbucket]
|
||||
- [Appium.exe for Windows][bitbucket]
|
||||
|
||||
[bitbucket]: https://bitbucket.org/appium/appium.app/downloads/
|
||||
[bitbucket]: https://bitbucket.org/appium/appium.app/downloads/
|
||||
|
||||
+55
-16
@@ -64,10 +64,10 @@ it yourself:
|
||||
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
|
||||
# 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.
|
||||
> ios_webkit_debug_proxy -c 0e4b2f612b65e98c1d07d22ee08678130d345429:27753 -d
|
||||
```
|
||||
```
|
||||
|
||||
**NOTE:** the proxy requires the **"web inspector"** to be turned on to
|
||||
allow a connection to be established. Turn it on by going to **settings >
|
||||
@@ -107,23 +107,23 @@ part of iOS 6** and was not available previously.
|
||||
//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");
|
||||
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 contextHandle : remoteWebDriver.getContexts()){
|
||||
remoteWebDriver.switchTo().context(contextHandle);
|
||||
}
|
||||
|
||||
|
||||
//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().context('NATIVE_APP')
|
||||
|
||||
|
||||
//close the app.
|
||||
remoteWebDriver.quit();
|
||||
```
|
||||
@@ -132,7 +132,7 @@ part of iOS 6** and was not available previously.
|
||||
|
||||
```ruby
|
||||
TEST_NAME = "Example Ruby Test"
|
||||
SERVER_URL = "http://127.0.0.1:4723/wd/hub"
|
||||
SERVER_URL = "http://127.0.0.1:4723/wd/hub"
|
||||
APP_PATH = "https://dl.dropboxusercontent.com/s/123456789101112/ts_ios.zip"
|
||||
capabilities =
|
||||
{
|
||||
@@ -148,13 +148,13 @@ capabilities =
|
||||
# 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
|
||||
Given(/^I switch to webview$/) do
|
||||
webview = @driver.contexts.last
|
||||
@driver.switch_to.context(webview)
|
||||
end
|
||||
|
||||
Given(/^I switch out of webview$/) do
|
||||
@driver.switch_to(@driver.contexts.first)
|
||||
@driver.switch_to(@driver.contexts.first)
|
||||
end
|
||||
|
||||
# Now you can use CSS to select an element inside your webview
|
||||
@@ -171,6 +171,32 @@ 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
|
||||
|
||||
## Wd.py Code example
|
||||
|
||||
```python
|
||||
APP_PATH = "https://dl.dropboxusercontent.com/s/123456789101112/ts_ios.zip"
|
||||
capabilities = {
|
||||
'browserName': 'iOS 6.0',
|
||||
'platform': 'Mac 10.8',
|
||||
'device': 'iPhone Simulator',
|
||||
'app': APP_PATH,
|
||||
'name': "Example Python Test"
|
||||
}
|
||||
driver = webdriver.Remote('http://localhost:4723/wd/hub', capabilities)
|
||||
|
||||
# switch to webview
|
||||
webview = driver.contexts.last
|
||||
driver.switch_to.context(webview)
|
||||
|
||||
# do some webby stuff
|
||||
driver.find_element(:css, ".green_button").click
|
||||
|
||||
# switch back to native view
|
||||
driver.switch_to(driver.contexts.first)
|
||||
|
||||
# Now you can use CSS to select an element inside your webview
|
||||
```
|
||||
|
||||
## Automating hybrid Android apps
|
||||
|
||||
Appium comes with built-in hybrid support via Chromedriver. Appium also uses
|
||||
@@ -203,21 +229,34 @@ driver.context("WEBVIEW", function(err) { // choose the only available view
|
||||
//setup the web driver and launch the webview app.
|
||||
DesiredCapabilities desiredCapabilities = new DesiredCapabilities();
|
||||
desiredCapabilities.setCapability("device", "Selendroid");
|
||||
desiredCapabilities.setCapability("app", "/path/to/some.apk");
|
||||
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().context("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().context("NATIVE_APP");
|
||||
|
||||
|
||||
//close the app.
|
||||
remoteWebDriver.quit();
|
||||
```
|
||||
```
|
||||
|
||||
## Wd.py Code example
|
||||
|
||||
```python
|
||||
# assuming we have an initialized `driver` object working on a hybrid app
|
||||
driver.switch_to.context("WEBVIEW")
|
||||
elements = driver.find_elements_by_css_selector('.some-class')
|
||||
assertLess(0, len(elements))
|
||||
assertEqual('My very own text', elements[0].text)
|
||||
|
||||
driver.switch_to.context("NATIVE_APP")
|
||||
driver.quit()
|
||||
```
|
||||
|
||||
+36
-1
@@ -23,6 +23,14 @@ Then, use desired capabilities like these to run your test in mobile Safari:
|
||||
}
|
||||
```
|
||||
|
||||
```python
|
||||
{
|
||||
'app': 'safari',
|
||||
'device': 'iPhone Simulator',
|
||||
'version': '6.1'
|
||||
}
|
||||
```
|
||||
|
||||
## Mobile Safari on a Real iOS Device
|
||||
|
||||
To be able to run your tests against mobile Safari we use the [SafariLauncher
|
||||
@@ -73,7 +81,7 @@ $ node /lib/server/main.js -U <UDID>
|
||||
|
||||
## Running your test
|
||||
|
||||
To configure you test to run against safari simpley set the **"app"** to be **"safari"**.
|
||||
To configure you test to run against safari simply set the **"app"** to be **"safari"**.
|
||||
|
||||
## Java Example
|
||||
|
||||
@@ -94,6 +102,26 @@ remoteWebDriver.findElement(By.id("comments")).sendKeys("My comment"); //populat
|
||||
remoteWebDriver.quit();
|
||||
```
|
||||
|
||||
## Python Example
|
||||
|
||||
```python
|
||||
# setup the web driver and launch the webview app.
|
||||
capabilities = { 'app': 'safari' }
|
||||
driver = webdriver.Remote('http://localhost:4723/wd/hub', capabilities)
|
||||
|
||||
# Navigate to the page and interact with the elements on the guinea-pig page using id.
|
||||
driver.get('http://saucelabs.com/test/guinea-pig');
|
||||
div = driver.find_element_by_id('i_am_an_id')
|
||||
# check the text retrieved matches expected value
|
||||
assertEqual('I am a div', div.text)
|
||||
|
||||
# populate the comments field by id
|
||||
driver.find_lement_by_id('comments').send_keys('My comment')
|
||||
|
||||
# close the driver
|
||||
driver.quit()
|
||||
```
|
||||
|
||||
## Mobile Chrome on Emulator or Real Device
|
||||
|
||||
Pre-requisites:
|
||||
@@ -109,3 +137,10 @@ Then, use desired capabilities like these to run your test in Chrome:
|
||||
, device: 'Android'
|
||||
};
|
||||
```
|
||||
|
||||
```python
|
||||
{
|
||||
'app': 'chrome',
|
||||
'device': 'Android'
|
||||
};
|
||||
```
|
||||
|
||||
@@ -40,6 +40,15 @@ Then script your WebDriver test, sending in the following desired capabilities:
|
||||
}
|
||||
```
|
||||
|
||||
```python
|
||||
{
|
||||
'platformName': 'iOS',
|
||||
'platformVersion': '6.1',
|
||||
'deviceName': 'iPhone Simulator',
|
||||
'app': myApp
|
||||
}
|
||||
```
|
||||
|
||||
In this set of capabilities, `myApp` must be either:
|
||||
|
||||
* A local absolute path to your simulator-compiled .app directory or .zip
|
||||
@@ -85,6 +94,15 @@ Then script your WebDriver test, sending in the following desired capabilities:
|
||||
}
|
||||
```
|
||||
|
||||
```python
|
||||
{
|
||||
'platformName': 'Android',
|
||||
'platformVersion': '4.2',
|
||||
'deviceName': 'Android Emulator',
|
||||
'app': myApp
|
||||
}
|
||||
```
|
||||
|
||||
In this set of capabilities, `myApp` must be either:
|
||||
|
||||
* A local absolute path to your .apk or a .zip of it
|
||||
@@ -119,8 +137,19 @@ and specifying the Selendroid automation backend.
|
||||
}
|
||||
```
|
||||
|
||||
```python
|
||||
{
|
||||
'automationName': 'Selendroid',
|
||||
'platformName': 'Android',
|
||||
'platformVersion': '2.3',
|
||||
'deviceName': 'Android Emulator',
|
||||
'version': '2.3',
|
||||
'app': myApp
|
||||
}
|
||||
```
|
||||
|
||||
Now Appium will start up a Selendroid test session instead of the default test
|
||||
session. One of the downsides to using Selendroid is that its API differs
|
||||
sometimes significantly with Appium's. Therefore we recommend you thoroughly
|
||||
read [Selendroid's documentation](http://selendroid.io/native.html) before
|
||||
writing your scripts for older devices or hybrid apps.
|
||||
writing your scripts for older devices or hybrid apps.
|
||||
|
||||
Reference in New Issue
Block a user