mirror of
https://github.com/appium/appium.git
synced 2026-11-09 19:38:26 +08:00
Compare commits
62
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
53f283f03d | ||
|
|
2da45d2154 | ||
|
|
e4bfd7c9cf | ||
|
|
f3c4817bfa | ||
|
|
fb3ef327a0 | ||
|
|
3991ba3f79 | ||
|
|
e2a5546be1 | ||
|
|
16af4f49f4 | ||
|
|
88685dcb69 | ||
|
|
5a5748cb16 | ||
|
|
cdabc1cea7 | ||
|
|
deaf7c4835 | ||
|
|
b3f3b2132b | ||
|
|
47166af12c | ||
|
|
74e6419ab7 | ||
|
|
f95eb6c4f5 | ||
|
|
00aab07e2c | ||
|
|
d8fcc7d850 | ||
|
|
d027f64700 | ||
|
|
ce479a577d | ||
|
|
2ddb1208f4 | ||
|
|
df2a2a3da0 | ||
|
|
e10bb290ea | ||
|
|
f0f71faa15 | ||
|
|
964a511be9 | ||
|
|
8e9252f12e | ||
|
|
c57d17541e | ||
|
|
757c20e486 | ||
|
|
696e4dea3f | ||
|
|
2c52e4661c | ||
|
|
11f5a0f5c0 | ||
|
|
ea4e55ad20 | ||
|
|
215c649545 | ||
|
|
c05fd69088 | ||
|
|
369946f5c8 | ||
|
|
3f273bd5f7 | ||
|
|
b1a39ec8f0 | ||
|
|
5486055fd3 | ||
|
|
0fd38c8ab1 | ||
|
|
65d8f4a606 | ||
|
|
c0f3d7a311 | ||
|
|
aaad6acaa9 | ||
|
|
30629133ec | ||
|
|
f1f821c44d | ||
|
|
5817d3125a | ||
|
|
41a4c33fdc | ||
|
|
d7f9dba9a1 | ||
|
|
a66e159cc2 | ||
|
|
74dfda9a8d | ||
|
|
84377d91fe | ||
|
|
60c7d73c39 | ||
|
|
939fff4c91 | ||
|
|
19fd7646a4 | ||
|
|
aa295a481e | ||
|
|
faabdc1942 | ||
|
|
0a80b7f5ac | ||
|
|
2e9181db93 | ||
|
|
657a83bdcb | ||
|
|
e5ca5b55fc | ||
|
|
6624802ece | ||
|
|
790d9e8df0 | ||
|
|
ec3e0bc7b3 |
+2
-1
@@ -1,7 +1,8 @@
|
||||
language: node_js
|
||||
sudo: false
|
||||
node_js:
|
||||
- "stable"
|
||||
- "7"
|
||||
- "6"
|
||||
- "4"
|
||||
script:
|
||||
- npm run lint
|
||||
|
||||
+210
@@ -1,3 +1,213 @@
|
||||
CHANGES IN VERSION 1.6.4 Beta (from 1.6.3)
|
||||
===================================
|
||||
|
||||
**Note:** This is a **_BETA_** release. Please direct any issues to the [Appium
|
||||
issue tracker](https://github.com/appium/appium/issues) and provide as much
|
||||
information as possible.
|
||||
|
||||
#### General
|
||||
* Fixed `UnhandledPromiseRejection` errors when running Appium with Node version
|
||||
7
|
||||
* Better indicate missing necessary programs to users
|
||||
* Fix session creation logging
|
||||
* Fix server shutdown on `SIGINT` and `SIGTERM` signals
|
||||
* Ensure that all requests have `application/json` content-type
|
||||
|
||||
#### iOS
|
||||
* Fix issues with error handling in Safari/Webview handling
|
||||
* Increase simulator launch timeout for iOS 10+
|
||||
* Better handling of page selection in Safari
|
||||
* Fix memory usage issues when device logs get large
|
||||
|
||||
#### iOS - XCUITest
|
||||
* Changed the way the Appium checks that WebDriverAgent is running on the device,
|
||||
so that rather than searching the logs, the device is pinged until it is
|
||||
ready.
|
||||
- Removed `realDeviceLogger` capability, since we no longer check the logs
|
||||
* Add `useNewWDA` capability, which forces uninstall of the WDA app from the
|
||||
device before each session
|
||||
* Add `wdaLaunchTimeout` capability, which specified the time, in `ms`, to wait
|
||||
for WDA to be loaded and launched on the device
|
||||
* Allow for the auto-generation of the Xcode config file used to configurable
|
||||
WDA before launch. This includes _two_ new desired capabilities
|
||||
- `xcodeOrgId` - the Apple developer team identifier string
|
||||
- `xcodeSigningId` - a string representing a signing certificate, defaulting to
|
||||
"iPhone Developer"
|
||||
* Allow for automatic changing of bundle id for WDA in cases where a
|
||||
provisioning profile cannot be made for default bundle
|
||||
- add `updatedWDABundleId` capability to specify bundle id for which there is
|
||||
a valid provisioning profile
|
||||
* Speed up setting the value of text fields
|
||||
* Add `wdaConnectionTimeout` to control how long the server waits for WDA to
|
||||
allow connections
|
||||
* Fix handling of local port on real devices
|
||||
* Speed up Safari interactions
|
||||
* Fix session deletion to ensure that clean up happens
|
||||
* Add `mobile: swipe` execute method
|
||||
* Ensure that scrolling through `mobile: scroll` works in web context
|
||||
|
||||
#### Android
|
||||
* Default installation to ChromeDriver 2.26
|
||||
* Add device manufacturer, model, and screen size to session details
|
||||
* Fix bug in checking avd status on some systems
|
||||
* Allow wildcards in `appWaitActivity` capability
|
||||
|
||||
#### Android - Selendroid
|
||||
* Fix handling of host binary configuration for more precise installation options
|
||||
|
||||
|
||||
CHANGES IN VERSION 1.6.3 (from 1.6.2)
|
||||
===================================
|
||||
|
||||
_This is another emergency release due to an issue with the NPM shrinkwrap_
|
||||
|
||||
#### iOS
|
||||
|
||||
* Fix issue where we might try and uninstall an ssl cert from a real device
|
||||
where this isn't sensible
|
||||
* Fix another issue with acceptSslCerts where it might potentially miss the
|
||||
correct sim UDID
|
||||
|
||||
#### iOS - XCUITest
|
||||
* Upgrade version of WebDriverAgent used. Includes following updates:
|
||||
* Improve xpath query performance
|
||||
* Verify predicates
|
||||
* Fix crash for some xpath selectors
|
||||
* Decorate proxied getSession response with Appium's capabilities (fixes
|
||||
issues with clients that call getSession to determine server capabilities
|
||||
and are confused by WDA's non-standard response) ([#7480](https://github.com/appium/appium/issues/7480))
|
||||
* Fix issue with starting XCUITests on a real device, due to changes in WDA
|
||||
that invalidated our startup detection logic. ([#7313](https://github.com/appium/appium/issues/7313))
|
||||
* Allow connecting to an already-running WebDriverAgent through the
|
||||
`webDriverAgentUrl` capability, rather than starting our own
|
||||
|
||||
#### Android
|
||||
* Fix bug where we would attempt to get target SDK version from manifests
|
||||
even when they might not include it. ([#7353](https://github.com/appium/appium/issues/7353))
|
||||
* Actually pass the `acceptSslCerts` capability to the underlying automation
|
||||
so that it can have an effect ([#7326](https://github.com/appium/appium/issues/7326))
|
||||
* Updated permission granting logic to speed up permission granting by doing
|
||||
it in bulk rather than one at a time ([#7493](https://github.com/appium/appium/issues/7493))
|
||||
* Hide the new permission granting logic behind an `autoGrantPermissions`
|
||||
capability which doesn't attempt to grant permissions unless it's `true`
|
||||
([#7497](https://github.com/appium/appium/issues/7497))
|
||||
|
||||
#### Android - Uiautomator2
|
||||
|
||||
* Add ability to verify TOAST messages (these can't be interacted with, only
|
||||
text retrieval allowed)
|
||||
|
||||
#### Windows
|
||||
* _Actually_ upgrade WinAppDriver to 0.7 ([#7445](https://github.com/appium/appium/issues/7445)). Includes following updates:
|
||||
* Click on arbitrary elements
|
||||
* Support for sendKeys modifiers
|
||||
* Various bugfixes
|
||||
* Added `GET /orientation`
|
||||
* Added support for WPF apps
|
||||
|
||||
|
||||
CHANGES IN VERSION 1.6.2 (from 1.6.1)
|
||||
===================================
|
||||
|
||||
_This is a small, mostly-emergency release because we realized we omitted
|
||||
XCUITest upgrades via WebDriverAgent that we had mistakenly presumed were part
|
||||
of 1.6.1._
|
||||
|
||||
#### iOS - XCUITest
|
||||
* Upgrade version of WebDriverAgent used. Includes following updates:
|
||||
* Support for setting values on sliders
|
||||
* Fix tapping in various orientations
|
||||
* Allow tapping on arbitrary coordinates
|
||||
* Support for pinch gestures
|
||||
* Make `clear` faster
|
||||
* Improve xpath query performance
|
||||
* Add `preventWDAAttachments` capability to help with XCUITest speed and disk usage
|
||||
|
||||
#### Android - UiAutomator2
|
||||
* Code refactoring to pave the way for some UiAutomator2 wifi automation work
|
||||
* Find an unused system port automatically to avoid port clashes
|
||||
|
||||
#### Windows
|
||||
* Upgrade WinAppDriver to 0.7. Includes following updates:
|
||||
* Click on arbitrary elements
|
||||
* Support for sendKeys modifiers
|
||||
* Various bugfixes
|
||||
* Added `GET /orientation`
|
||||
* Added support for WPF apps
|
||||
|
||||
|
||||
CHANGES IN VERSION 1.6.1 (from 1.6.0)
|
||||
===================================
|
||||
|
||||
Appium 1.6.1 is the first release since bringing Appium into the [JS Foundation](https://js.foundation/)
|
||||
(see [press release](https://js.foundation/announcements/2016/10/17/Linux-Foundation-Unites-JavaScript-Community-Open-Web-Development/)).
|
||||
|
||||
Much of the development energy has been spent on fixing issues that have come up
|
||||
from the newly-integrated XCUITest and UI Automator 2 vendor-provided test
|
||||
backends.
|
||||
|
||||
#### General
|
||||
* Add `clearSystemFiles` desired capability, to specify whether to delete any generated
|
||||
files at the end of a session (see iOS and Android entries for particulars)
|
||||
* Better handle signals for stopping server
|
||||
* Fix operation of Selenium 3 Grid
|
||||
* Log more of the proxied requests and responses, for better debugging
|
||||
* Better handle source mapping for IDE support
|
||||
* Move `appium-doctor` into globally-installed utility, not bundled with server
|
||||
* Move `appium-logger` into `appium-base-driver`
|
||||
* Better handle downloading of zip files which may not have a `.zip` extension (like `.apk`)
|
||||
|
||||
|
||||
##### iOS
|
||||
* Add support for iOS 10.1
|
||||
* Add support for iOS 10.2 Beta 1
|
||||
* Add `clearSystemFiles` desired capability to specify whether to Core Simulator
|
||||
files, and Instruments (for iOS Driver) or XCUITest (for XCUITest Driver) generated files
|
||||
* Ensure correct files are tested when checking for Simulator newness
|
||||
* Map `iPad Simulator` `deviceName` to iPad Retina instead of discontinued iPad 2
|
||||
* Gracefully return when Webkit Remote Debugger doesn't return on a real device
|
||||
* Better log errors from xcode handling
|
||||
* Add `customSSLCert` capability to pre-authorize a specific SSL cert in the iOS trust store
|
||||
* During reset, don't try to uninstall an app from a real device if it's not installed
|
||||
|
||||
|
||||
##### iOS - XCUITest specific
|
||||
* clean up logging to remove confusing "Waiting..." lines
|
||||
* Fix issue in which switching to NATIVE_APP would still proxy find commands to Remote debugger
|
||||
* Fix handling of Selenium Grids
|
||||
* Correctly handle long press so duration is respected
|
||||
* Add `tapWithShortPressDuration` desired capability to specify a length for tapping,
|
||||
if the regular tap is too long for the app under test
|
||||
* Add support for scrolling through Touch Actions
|
||||
* Make sure keyboard is available when keys are sent to Text Fields
|
||||
* Add support for Zoom via Touch Action API (Pinch still not supported by Apple)
|
||||
* Fix implementation of double tap
|
||||
* Improvements in startup flow for real devices
|
||||
* Allow gestures on coordinates, not just elements
|
||||
* Add `scaleFactor` capability to direct Appium to set the simulator scale
|
||||
|
||||
|
||||
##### Android
|
||||
* Use ChromeDriver version 2.25
|
||||
* Correctly handle `--suppress-adb-kill-server` command line argument
|
||||
* Pass actual failure back when session fail and deleting the session also fails
|
||||
* Add `clearSystemFiles` desired capability to specify whether to delete temporary
|
||||
copies of the application under test at the end of the session
|
||||
* Fix issue where finding UI Automator process id would throw an error
|
||||
* Add `chromeAndroidPackage` capability which will be passed to `chromeOptions`
|
||||
* Add APIs for gathering various kinds of performance data
|
||||
* Ensure we don't try to stop app if `dontStopAppOnReset` is in force
|
||||
* Fix issue where we tried to determine the bounds of a non-existent element
|
||||
|
||||
|
||||
##### Android - UiAutomator2
|
||||
* Fix handling of element attributes
|
||||
* Better handle element finding
|
||||
* Toast message verification support
|
||||
* Ensure that there is a <hierarchy> root tag for xml/xpath source
|
||||
* Implement /rotation endpoint (supports 4 rotations)
|
||||
|
||||
|
||||
CHANGES IN VERSION 1.6.0 (from 1.5.3)
|
||||
===================================
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Copyright 2012-2016 Sauce Labs, Inc.
|
||||
Copyright 2012-2016 JS Foundation and other contributors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
[](https://team-appium.ci.cloudbees.com/job/Appium/)
|
||||
|
||||
Appium is an open source, cross-platform test automation tool for native, hybrid and mobile web apps, tested on simulators (iOS, FirefoxOS), emulators (Android), and real devices (iOS, Android, Windows, FirefoxOS).
|
||||
Appium is an open source, cross-platform test automation tool for native, hybrid and mobile web apps, tested on simulators (iOS), emulators (Android), and real devices (iOS, Android, Windows).
|
||||
|
||||
|
||||
### Supported Platforms
|
||||
@@ -18,7 +18,6 @@ Appium is an open source, cross-platform test automation tool for native, hybrid
|
||||
* iOS
|
||||
* Android
|
||||
* Windows
|
||||
* FirefoxOS
|
||||
|
||||
See the [platform support doc](/docs/en/appium-setup/platform-support.md) for more detailed information.
|
||||
|
||||
@@ -77,16 +76,12 @@ You also need to download the Appium client for your language so you can write t
|
||||
* [linux](/docs/en/appium-setup/running-on-linux.md)
|
||||
* [osx](/docs/en/appium-setup/running-on-osx.md)
|
||||
* [windows](/docs/en/appium-setup/running-on-windows.md)
|
||||
|
||||
|
||||
#### Windows Requirements
|
||||
|
||||
* Windows 10
|
||||
* [Documentation](/docs/en/appium-setup/running-on-windows.md)
|
||||
|
||||
#### FirefoxOS Requirements
|
||||
|
||||
* [Firefox OS Simulator](https://developer.mozilla.org/en/docs/Tools/Firefox_OS_Simulator)
|
||||
|
||||
### Quick Start
|
||||
|
||||
Kick up an Appium server, and then run a test written in your favorite [WebDriver](https://w3c.github.io/webdriver/webdriver-spec.html)-compatible language!
|
||||
@@ -99,7 +94,14 @@ $ npm install -g appium
|
||||
$ appium
|
||||
```
|
||||
|
||||
#### Using the App
|
||||
As we said above, you may want to run `appium-doctor` to ensure your system is set up properly:
|
||||
|
||||
```
|
||||
$ npm install -g appium-doctor
|
||||
$ appium-doctor
|
||||
```
|
||||
|
||||
#### Using the Appium Desktop App
|
||||
|
||||
* [Download the Appium app](https://bitbucket.org/appium/appium.app/downloads/)
|
||||
* Run it!
|
||||
@@ -108,6 +110,8 @@ $ appium
|
||||
|
||||
The main guide for getting started writing and running tests is [the running tests](/docs/en/writing-running-appium/running-tests.md) doc, which includes explanations for iOS, Android, and Android older devices. If you're interested in testing on physical hardware, you might be interested in our [real devices guide](/docs/en/appium-setup/real-devices.md).
|
||||
|
||||
(*Note*: If you're automating iOS 10+, be sure to check out our [XCUITest Migration Guide](/docs/en/advanced-concepts/migrating-to-xcuitest.md) since Apple's automation support has changed significantly since iOS 10, with corresponding changes in Appium).
|
||||
|
||||
Essentially, we support a subset of the [Selenium WebDriver JSON Wire Protocol](https://w3c.github.io/webdriver/webdriver-spec.html), and extend it so that you can specify mobile-targeted [desired capabilities](/docs/en/writing-running-appium/caps.md) to run your test through Appium.
|
||||
|
||||
You find elements by using a subset of WebDriver's element-finding strategies.
|
||||
@@ -124,18 +128,15 @@ For the full list of Appium doc pages, visit [this directory](/docs/en/).
|
||||
Appium drives various native automation frameworks and provides an API based on
|
||||
Selenium's [WebDriver JSON wire protocol](https://w3c.github.io/webdriver/webdriver-spec.html).
|
||||
|
||||
Appium drives Apple's UIAutomation library for iOS support, which is based on
|
||||
[Dan Cuellar's](http://github.com/penguinho) work on iOS Auto.
|
||||
For new iOS versions (9.3 and up), Appium drives Apple's XCUITest library. Our support for XCUITest utilizes Facebook's [WebDriverAgent](https://github.com/facebook/webdriveragent) project.
|
||||
|
||||
For older iOS versions (9.3 and below), Appium drives Apple's UIAutomation library, using a strategy which is based on [Dan Cuellar's](http://github.com/penguinho) work on iOS Auto.
|
||||
|
||||
Android support uses the UiAutomator framework for newer platforms and
|
||||
[Selendroid](http://github.com/DominikDary/selendroid) for older Android platforms.
|
||||
|
||||
Windows support uses Microsoft's [WinAppDriver](https://github.com/Microsoft/WinAppDriver)
|
||||
|
||||
FirefoxOS support leverages [Marionette](https://developer.mozilla.org/en-US/docs/Marionette),
|
||||
an automation driver that is compatible with WebDriver and is used to automate
|
||||
Gecko-based platforms.
|
||||
|
||||
### Contributing
|
||||
|
||||
Please take a look at our [contribution documentation](CONTRIBUTING.md)
|
||||
@@ -145,11 +146,12 @@ for instructions on how to build, test and run Appium from source.
|
||||
|
||||
Interested in where Appium is heading in the future? Check out the [Roadmap](ROADMAP.md)
|
||||
|
||||
### Project Credits & Inspiration
|
||||
### Project History, Credits & Inspiration
|
||||
|
||||
[Credits](/docs/en/contributing-to-appium/credits.md)
|
||||
* [History](http://appium.io/history)
|
||||
* [Credits](/docs/en/contributing-to-appium/credits.md)
|
||||
|
||||
### Mailing List
|
||||
### User Forums
|
||||
|
||||
Announcements and debates often take place on the [Discussion Group](https://discuss.appium.io), be sure to sign up!
|
||||
|
||||
|
||||
+20
-10
@@ -17,31 +17,41 @@ exists to outline large-scale future plans for Appium.
|
||||
|
||||
| Project | Description | ETD | Projected Appium Release |
|
||||
|---------|-------------|-----|--------------------------|
|
||||
|[Architecture Overhaul](https://github.com/appium/appium/issues/5169)|Appium's architecture has grown unwieldy enough that adding new features and preventing regressions has become difficult. A rearchitecture is in order to solve these issues as well as migrate the codebase to a form of JS much easier to work in and understand.|1/2016|1.5|
|
||||
|XCUITest backend integration|Instruments + UIAutomation has been working well for many Appium users, but requires crazy workarounds to deal with bugs which remain unfixed on the Apple side. We should explore Apple's newer technology, XCUITest, in order to see if the overall experience is more stable. This new backend would exist alongside the UIAutomation backend.|3/2016?|Beta in 1.6?|
|
||||
|UiAutomator2 backend integration|Google has released [UiAutomator 2](http://developer.android.com/reference/android/support/test/uiautomator/package-summary.html), and it promises to fix some issues and limitations with the previous UiAutomator support. We will build this inside of Selendroid since it requires an instrumentation context.|3/2016?|TBD|
|
||||
|iOS 9.3 support|Appium should support iOS 9.3 / Xcode 7.3|2/2016|1.6?||
|
||||
|[Android 7.0 Support](https://github.com/appium/appium/issues/7156)|Support Android 7 (Nougat)|11/2016|1.6.1|
|
||||
|[New Appium GUIs](https://github.com/appium/appium/issues/7167)|The current Appium GUIs (Appium.app and Appium.exe) have a number of issues. They aren't maintained by the core Appium team. They're written in Objective-C and C# respectively: two languages, and specifically, two languages other than Appium's core language. Because of this they lag behind the Appium server and are often broken. However, users love them primarily because of the Inspector feature (the thing that lets them graphically navigate their app), so we have to field a ton of complaints about these projects. There's an opportunity to start over. With [Electron](http://electron.atom.io/), we'd be able to take the new version of Appium we're working on and embed it directly inside a Node-based GUI app written using the languages and technologies the core team is experienced with. We'd have one codebase and could distribute the app on Mac, Windows, and Linux. The GUIs would become an official part of Appium's release cycle so they wouldn't be broken.|Q1 2017|N/A|
|
||||
|
||||
## Upcoming Projects (in rough order of priority)
|
||||
|
||||
| Project | Description |
|
||||
|---------|-------------|
|
||||
|Apple Watch support|Appium should support Apple Watch apps via the Watch simulator|
|
||||
|Onboarding Overhaul|The current Appium docs leave a lot to be desired. The format is confusing (it would be better for API docs), the content is outdated, and many things are still undocumented. This project would go back to the drawing board in all of these areas and put together something genuinely helpful for the community, which hopefully reduces the kind of support issues we're currently flooded by.|
|
||||
|New Appium GUIs|The current Appium GUIs (Appium.app and Appium.exe) have a number of issues. They aren't maintained by the core Appium team. They're written in Objective-C and C# respectively: two languages, and specifically, two languages other than Appium's core language. Because of this they lag behind the Appium server and are often broken. However, users love them primarily because of the Inspector feature (the thing that lets them graphically navigate their app), so we have to field a ton of complaints about these projects. There's an opportunity to start over. With [Electron](http://electron.atom.io/), we'd be able to take the new version of Appium we're working on and embed it directly inside a Node-based GUI app written using the languages and technologies the core team is experienced with. We'd have one codebase and could distribute the app on Mac, Windows, and Linux. The GUIs would become an official part of Appium's release cycle so they wouldn't be broken.|
|
||||
|Unity3d backend POC|This is a research project to determine whether we can add some kind of support for 3d game automation, probably based on the Unity3d game development platform.|
|
||||
|Dynamic Test App|Our current test applications (the ones used to test Appium's iOS and Android support) are not ideal. We use too many of them and the ones we use have a random hodgepodge of app SDK features, sometimes not enough to sufficiently test automation support. Using [Titanium](https://github.com/appcelerator/titanium_mobile), we can develop an app that allows us to inject whatever native code we need, as we need it. The app thus changes itself test-by-test to have whatever UI features we need for that particular test. It gives us much more fine-grained control over what we're testing. The app code would also be cross-platform and written in JS, which would make it easier for the core team to write and maintain.|
|
||||
|[Android 7.1.1 Support](https://github.com/appium/appium/issues/7165)|Google has released Android 7.1.1 (API Level 25). Ensure it works with UiAutomator 1/2|
|
||||
|[Appium CI + Metrics Improvements](https://github.com/appium/appium/issues/7168)|We have CI servers running via Cloudbees that we don't understand and which break. Let's document and own them so they work reliably. Also, let's implement gathering various metrics about driver performance so we can track this over time and ensure we're not releasing a driver which has decreased in performance or reliability.|
|
||||
|[Onboarding Overhaul](https://github.com/appium/appium/issues/7169)|The current Appium docs leave a lot to be desired. The format is confusing (it would be better for API docs), the content is outdated, and many things are still undocumented. This project would go back to the drawing board in all of these areas and put together something genuinely helpful for the community, which hopefully reduces the kind of support issues we're currently flooded by.|
|
||||
|[Appium Client Library Updates](https://github.com/appium/appium/issues/7170)|It's been too long since we ensured that Appium's client libraries were up to date with the server|
|
||||
|[Sample Code Overhaul](https://github.com/appium/appium/issues/7171)|Our sample code repo has grown tangled and broken. Let's make a new one with minimal examples which are the same across every language, and actually maintain the repo so as not to let it become overgrown.|
|
||||
|[Test App Overhaul](https://github.com/appium/appium/issues/7172)|Our current test applications (the ones used to test Appium's iOS and Android support) are not ideal. We use too many of them and the ones we use have a random hodgepodge of app SDK features, sometimes not enough to sufficiently test automation support. It'd be great to find a way to ensure our test app(s) have all the features we need to test, and keep in sync with our requirements.|
|
||||
|[iOS Test Startup Time Improvement](https://github.com/appium/appium/issues/7173)|iOS startup times have gotten progressively longer with each iOS release. In part this is Apple's fault and there's not anything we can do about it. But we should investigate and see if we can be more efficient in how we start, especially given that we can now focus on XCUITest and leave Instruments behind|
|
||||
|[Appium Dearchitecture](https://github.com/appium/appium/issues/7174)|OK, we went a bit overboard in Appium 1.5 by exploding Appium into 40+ repos and NPM packages. Let's think a little more critically about it and consolidate into the minimal number of repos/packages that make sense for our code and community patterns.|
|
||||
|[Appium 2.0](https://github.com/appium/appium/issues/7175)|Appium, rather than bundling all the separate drivers by default, becomes a driver management interface (in addition to continuing to play the role of automation frontend server). Appium gets a set of CLI tools for users to pick and choose which drivers and versions of drivers they want to use via Appium|
|
||||
|
||||
## Projects Under Consideration (unprioritized)
|
||||
## Projects Under Consideration (unplanned and unprioritized)
|
||||
|
||||
| Project | Description |
|
||||
|---------|-------------|
|
||||
|Windows Phone Support|There has been some work done on automating Windows Phone apps. We could take this all the way to integration with Appium in the form of a WindowsDriver.|
|
||||
|Apple Watch support|Appium should support Apple Watch apps via the Watch simulator|
|
||||
|Unity3d backend POC|This is a research project to determine whether we can add some kind of support for 3d game automation, probably based on the Unity3d game development platform.|
|
||||
|
||||
## Completed Roadmap Projects
|
||||
|
||||
| Project | Description | Completed | Appium Release | Notes |
|
||||
|---------|-------------|-----------|----------------|-------|
|
||||
|[iOS 10.2 Support](https://github.com/appium/appium/issues/7166)|Support iOS 10.2|11/2016|1.6.1||
|
||||
|[iOS 10.1 Support](https://github.com/appium/appium/issues/7105)|Support iOS 10.1|11/2016|1.6.1||
|
||||
|UiAutomator2 integration|Google has released [UiAutomator 2](http://developer.android.com/reference/android/support/test/uiautomator/package-summary.html), and it promises to fix some issues and limitations with the previous UiAutomator support. We will build this inside of Selendroid since it requires an instrumentation context.|10/2016?|1.6.0|
|
||||
|XCUITest integration / iOS 10 support|Instruments + UIAutomation has been working well for many Appium users, but requires crazy workarounds to deal with bugs which remain unfixed on the Apple side. Also, UIAutomation has been removed in favor of XCUITest for iOS 10+. This new backend would exist alongside the UIAutomation backend.|10/2016|1.6.0||
|
||||
|iOS 9.3 support|Appium should support iOS 9.3 / Xcode 7.3|3/2016|1.5.1||
|
||||
|[Architecture Overhaul](https://github.com/appium/appium/issues/5169)|Appium's architecture has grown unwieldy enough that adding new features and preventing regressions has become difficult. A rearchitecture is in order to solve these issues as well as migrate the codebase to a form of JS much easier to work in and understand.|2/2015|1.5.0||
|
||||
|iOS 9.2 support|Appium should support iOS 9.2 / Xcode 7.2|11/2015|1.4.14||
|
||||
|iOS 9.1 support|Appium should support iOS 9.1 / Xcode 7.1|10/2015|1.4.12||
|
||||
|iOS 9.0 support|Appium should support iOS 9.0 / Xcode 7.0|10/2015|1.4.11||
|
||||
|
||||
@@ -1,13 +1,6 @@
|
||||
## Introduction to Appium
|
||||
|
||||
Appium is an open-source tool for automating native,
|
||||
mobile web, and hybrid applications on iOS and Android platforms.
|
||||
**Native apps** are those written using the iOS, Android, or Windows SDKs. **Mobile web apps** are web apps accessed using a mobile browser (Appium supports
|
||||
Safari on iOS and Chrome or the built-in 'Browser' app on Android). **Hybrid apps** have a
|
||||
wrapper around a "webview" -- a native control that enables interaction with
|
||||
web content. Projects like [Phonegap](http://phonegap.com/),
|
||||
make it easy to build apps using web technologies that are then bundled into
|
||||
a native wrapper, creating a hybrid app.
|
||||
Appium is an open-source tool for automating native, mobile web, and hybrid applications on iOS mobile, Android mobile, and Windows desktop platforms. **Native apps** are those written using the iOS, Android, or Windows SDKs. **Mobile web apps** are web apps accessed using a mobile browser (Appium supports Safari on iOS and Chrome or the built-in 'Browser' app on Android). **Hybrid apps** have a wrapper around a "webview" -- a native control that enables interaction with web content. Projects like [Phonegap](http://phonegap.com/), make it easy to build apps using web technologies that are then bundled into a native wrapper, creating a hybrid app.
|
||||
|
||||
Importantly, Appium is "cross-platform": it allows you to write tests against
|
||||
multiple platforms (iOS, Android, Windows), using the same API. This enables code reuse between iOS, Android, and Windows testsuites.
|
||||
@@ -31,10 +24,11 @@ meet requirement #1 by using vendor-provided automation frameworks under the
|
||||
hood. That way, we don't need to compile in any Appium-specific or
|
||||
third-party code or frameworks to your app. This means **you're testing the same app you're shipping**. The vendor-provided frameworks we use are:
|
||||
|
||||
* iOS: Apple's [UIAutomation](https://developer.apple.com/library/ios/documentation/DeveloperTools/Reference/UIAutomationRef/)
|
||||
* iOS 9.3 and above: Apple's [XCUITest](https://developer.apple.com/reference/xctest)
|
||||
* iOS 9.3 and lower: Apple's [UIAutomation](https://developer.apple.com/library/ios/documentation/DeveloperTools/Reference/UIAutomationRef/)
|
||||
* Android 4.2+: Google's [UiAutomator](http://developer.android.com/tools/help/uiautomator/index.html)
|
||||
* Android 2.3+: Google's [Instrumentation](http://developer.android.com/reference/android/app/Instrumentation.html). (Instrumentation support is provided by bundling a separate project, [Selendroid](http://selendroid.io))
|
||||
* Windows: Microsoft's [WinAppDriver](http://github.com/microsoft/winappdriver)
|
||||
* Windows: Microsoft's [WinAppDriver](http://github.com/microsoft/winappdriver)
|
||||
|
||||
We meet requirement #2 by wrapping the vendor-provided frameworks in one API,
|
||||
the [WebDriver](http://docs.seleniumhq.org/projects/webdriver/) API.
|
||||
|
||||
@@ -31,18 +31,18 @@ Here are the steps required to talk to a web view in your Appium test:
|
||||
// javascript
|
||||
// assuming we have an initialized `driver` object for an app
|
||||
driver
|
||||
.contexts().then(function (contexts) { // get list of available views. Returns array: ["NATIVE_APP","WEBVIEW_1"]
|
||||
return driver.context(contexts[1]); // choose the webview context
|
||||
})
|
||||
.contexts().then(function (contexts) { // get list of available views. Returns array: ["NATIVE_APP","WEBVIEW_1"]
|
||||
return driver.context(contexts[1]); // choose the webview context
|
||||
})
|
||||
|
||||
// do some web testing
|
||||
.elementsByCss('.green_button').click()
|
||||
// do some web testing
|
||||
.elementsByCss('.green_button').click()
|
||||
|
||||
.context('NATIVE_APP') // leave webview context
|
||||
.context('NATIVE_APP') // leave webview context
|
||||
|
||||
// do more native stuff here if we want
|
||||
// do more native stuff here if we want
|
||||
|
||||
.quit() // stop webdrivage
|
||||
.quit() // stop webdrivage
|
||||
```
|
||||
|
||||
```java
|
||||
@@ -52,7 +52,7 @@ driver = new AppiumDriver(new URL("http://127.0.0.1:4723/wd/hub"), capabilities)
|
||||
|
||||
Set<String> contextNames = driver.getContextHandles();
|
||||
for (String contextName : contextNames) {
|
||||
System.out.println(contextNames); //prints out something like NATIVE_APP \n WEBVIEW_1
|
||||
System.out.println(contextNames); //prints out something like NATIVE_APP \n WEBVIEW_1
|
||||
}
|
||||
driver.context(contextNames.toArray()[1]); // set context to WEBVIEW_1
|
||||
|
||||
@@ -76,18 +76,18 @@ driver.quit();
|
||||
# Then switch to it using @driver.switch_to.context("WEBVIEW_6")
|
||||
|
||||
Given(/^I switch to webview$/) do
|
||||
webview = @driver.contexts.last
|
||||
@driver.switch_to.context(webview)
|
||||
webview = @driver.contexts.last
|
||||
@driver.switch_to.context(webview)
|
||||
end
|
||||
|
||||
Given(/^I switch out of webview$/) do
|
||||
@driver.switch_to.context(@driver.contexts.first)
|
||||
@driver.switch_to.context(@driver.contexts.first)
|
||||
end
|
||||
|
||||
# Now you can use CSS to select an element inside your webview
|
||||
|
||||
And(/^I click a webview button $/) do
|
||||
@driver.find_element(:css, ".green_button").click
|
||||
@driver.find_element(:css, ".green_button").click
|
||||
end
|
||||
```
|
||||
|
||||
@@ -116,23 +116,23 @@ driver.quit()
|
||||
|
||||
public function testThings()
|
||||
{
|
||||
$expected_contexts = array(
|
||||
0 => 'NATIVE_APP',
|
||||
1 => 'WEBVIEW_1'
|
||||
);
|
||||
$expected_contexts = array(
|
||||
0 => 'NATIVE_APP',
|
||||
1 => 'WEBVIEW_1'
|
||||
);
|
||||
|
||||
$contexts = $this->contexts();
|
||||
$this->assertEquals($expected_contexts, $contexts);
|
||||
$contexts = $this->contexts();
|
||||
$this->assertEquals($expected_contexts, $contexts);
|
||||
|
||||
$this->context($contexts[1]);
|
||||
$context = $this->context();
|
||||
$this->assertEquals('WEBVIEW_1', $context);
|
||||
$this->context($contexts[1]);
|
||||
$context = $this->context();
|
||||
$this->assertEquals('WEBVIEW_1', $context);
|
||||
|
||||
// do webby stuff
|
||||
// do webby stuff
|
||||
|
||||
$this->context('NATIVE_APP');
|
||||
$this->context('NATIVE_APP');
|
||||
|
||||
// do mobile stuff
|
||||
// do mobile stuff
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -50,12 +50,13 @@ Once installed you can start the proxy with the following command:
|
||||
> ios_webkit_debug_proxy -c 0e4b2f612b65e98c1d07d22ee08678130d345429:27753 -d
|
||||
```
|
||||
|
||||
You may also use the ios-webkit-debug-proxy-launcher to launch the
|
||||
You may also use `ios-webkit-debug-proxy-launcher`, a small script included with the Appium codebase, to launch the
|
||||
proxy. It monitors the proxy log for errors, and relaunch the proxy
|
||||
where needed. This is also optional and may help with recent devices:
|
||||
|
||||
``` center
|
||||
# change the udid
|
||||
# note, this is run from an Appium repository
|
||||
> ./bin/ios-webkit-debug-proxy-launcher.js -c 0e4b2f612b65e98c1d07d22ee08678130d345429:27753 -d
|
||||
```
|
||||
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
## Setting up instruments without delay (iwd) for xcode 7 and iOS >= 9.0
|
||||
|
||||
For iOS >= 9.0 instruments without delay (iwd) does not work by passing binaries through
|
||||
the command line (appium does this under the hood for xcode < 7). See [iwd](https://github.com/lawrencelomax/instruments-without-delay/tree/xcode7-quirks#xcode-7--ios-9-support)
|
||||
For iOS >= 9.0 instruments without delay (iwd) does not work by passing binaries through the command line (appium does this under the hood for xcode < 7). See [iwd](https://github.com/lawrencelomax/instruments-without-delay/tree/xcode7-quirks#xcode-7--ios-9-support)
|
||||
|
||||
For enabling iwd for xcode >= 7,
|
||||
- Checkout [appium-instruments](https://github.com/appium/appium-instruments)
|
||||
- Run `xcode-iwd.sh` present in `<appium-instruments>/bin/`
|
||||
- Check out [appium-instruments](https://github.com/appium/appium-instruments)
|
||||
- Run `xcode-iwd.sh` present in `<appium-instruments>/bin/`, with arguments as indicated below:
|
||||
|
||||
```
|
||||
sh <appium-instruments>/bin/xcode-iwd.sh <path to xcode> <path to appium-instruments>
|
||||
```
|
||||
eg. `sh ./bin/xcode-iwd.sh /Applications/Xcode.app /Users/xyz/appium-instruments/`
|
||||
|
||||
Note: iwd with xcode7 will only work for iOS >= 9.0, you can switch to older xcode for iOS < 9.0
|
||||
Note: iwd with Xcode 7 will only work for iOS >= 9.0, you can switch to an older version of Xcode for iOS < 9.0
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
*This document is old, and only of interest for those migrating to Appium 1.x from an earlier version*
|
||||
|
||||
## Migrating your tests from Appium 0.18.x to Appium 1.x
|
||||
|
||||
Appium 1.0 has removed a number of deprecated features from the previous versions. This guide will help you know what needs to change in your test suite to take advantage of Appium 1.0.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
## Migrating your iOS tests from UIAutomation (iOS 9.2 and below) to XCUITest (iOS 9.3 and up)
|
||||
## Migrating your iOS tests from UIAutomation (iOS 9.3 and below) to XCUITest (iOS 9.3 and up)
|
||||
|
||||
For iOS automation, Appium relies on system frameworks provided by Apple. For iOS 9.2 and below, Apple's only automation technology was called UIAutomation, and it ran in the context of a process called "Instruments". As of iOS 10, Apple has completely removed the UIAutomation instrument, thus making it impossible for Appium to allow testing in the way it used to. Fortunately, Apple introduced a new automation technology, called XCUITest, beginning with iOS 9.3. For iOS 10 and up, this will be the only supported automation framework from Apple.
|
||||
|
||||
@@ -21,6 +21,61 @@ As mentioned just above, if you rely on the app source XML from the `page source
|
||||
|
||||
This locator strategy was specifically built on UIAutomation, so it is not included in the XCUITest automation backend. We will be working on a similar "native"-type locator strategy in coming releases.
|
||||
|
||||
### `xpath` locator strategy
|
||||
|
||||
1. Try not to use XPath locators unless there is absolutely no other alternatives. In general, xpath locators might be times slower, than other types of locators like accessibility id, class name and predicate (up to 100 times slower in some special cases). They are so slow, because xpath location is not natively supported by Apple's XCTest framework.
|
||||
2. Use
|
||||
|
||||
```
|
||||
driver.findElement(x)
|
||||
```
|
||||
|
||||
call instead of
|
||||
|
||||
```
|
||||
driver.findElements(x)[0]
|
||||
```
|
||||
|
||||
to lookup single element by xpath. The more possible UI elements are matched by your locator the slower it is.
|
||||
3. Be very specific when locating elements by xpath. Such locators like
|
||||
|
||||
```
|
||||
//*
|
||||
```
|
||||
|
||||
may take minutes to complete depending on how many UI elements your application has (e. g.
|
||||
|
||||
```
|
||||
driver.findElement(By.xpath("//XCUIElementTypeButton[@value='blabla']"))
|
||||
```
|
||||
|
||||
is faster than
|
||||
|
||||
```
|
||||
driver.findElement(By.xpath("//*[@value='blabla']"))
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```
|
||||
driver.findElement(By.xpath("//XCUIElementTypeButton")))
|
||||
```
|
||||
|
||||
4. In most cases it would be faster to perform multiple nested findElement calls than to perform a single call by xpath (e.g.
|
||||
|
||||
```
|
||||
driver.findElement(x).findElement(y)
|
||||
```
|
||||
|
||||
is usually faster than
|
||||
|
||||
```
|
||||
driver.findElement(z)
|
||||
|
||||
```
|
||||
|
||||
where x and y are non-xpath locators and z is a xpath locator).
|
||||
|
||||
### System dependencies
|
||||
|
||||
In addition to the many gotchas that might come with upgrading any XCode installation (unrelated to Appium), Appium's XCUITest support requires a new system dependency: [Carthage](https://github.com/Carthage/Carthage). Appium Doctor has now been updated to ensure that the `carthage` binary is on your path.
|
||||
@@ -35,10 +90,21 @@ Unfortunately, the XCUITest API and the UIAutomation API are not equivalent. In
|
||||
|
||||
We will endeavor to add these features back in future releases of Appium.
|
||||
|
||||
#### Scrolling and clicking
|
||||
|
||||
In the previous UIAutomation-based driver, if you tried to click on an element that wasn't in view, UIAutomation would scroll to the element automatically and then tap it. With XCUITest, this is no longer the case. You are now responsible for ensuring your element is in view before interacting with it (the same way a user would be responsible for the same).
|
||||
|
||||
### Other known issues
|
||||
|
||||
Finally, a list of known issues with the initial 1.6 release:
|
||||
Finally, a list of known issues with the initial 1.6 release (we'll strike through issues which have been resolved):
|
||||
|
||||
* [Problems with processArguments](https://github.com/appium/appium/issues/6888)
|
||||
* ~~Unable to interact with elements on devices in Landscape mode (https://github.com/appium/appium/issues/6994)~~
|
||||
* `shake` is not implemented due to lack of support from Apple
|
||||
* `lock` is not implemented due to lack of support from Apple
|
||||
* Setting geo-location not supported due to lack of support from Apple
|
||||
* Through the TouchAction/MultiAction API, `zoom` gestures work but `pinch` gestures do not, due to an Apple issue.
|
||||
* Through the TouchAction/MultiAction API, `swipe` gestures are currently not supported, though they should be soon (https://github.com/appium/appium/issues/7573)
|
||||
* The capabilities `autoAcceptAlerts` and `autoDismissAlerts` do not currently work, and there is continued debate about whether we will be able to implement them in the future.
|
||||
* There is an issue with the iOS SDK such that PickerWheels built using certain API methods are not automatable by XCUITest. See https://github.com/appium/appium/issues/6962 for the workaround, to ensure your PickerWheels are built properly.
|
||||
|
||||
As far as possible, we will add the missing features and fix other known issues in the [1.6.1 Milestone](https://github.com/appium/appium/milestone/27), so following that may be of interest to you.
|
||||
As far as possible, we will add the missing features and fix other known issues in future versions of Appium.
|
||||
|
||||
@@ -21,8 +21,8 @@ Settings are implemented via the following API endpoints:
|
||||
```
|
||||
{
|
||||
settings: {
|
||||
ignoreUnimportantViews : true
|
||||
}
|
||||
ignoreUnimportantViews : true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -31,10 +31,12 @@ Settings are implemented via the following API endpoints:
|
||||
>Returns a JSON hash of all the currently specified settings.
|
||||
```
|
||||
{
|
||||
ignoreUnimportantViews : true
|
||||
ignoreUnimportantViews : true
|
||||
}
|
||||
```
|
||||
|
||||
Note that the actual commands you would use in your test script differ based on the language; see the specific Appium client documention for more information.
|
||||
|
||||
### Supported Settings
|
||||
|
||||
**"ignoreUnimportantViews"** - Boolean which sets whether Android devices should use `setCompressedLayoutHeirarchy()` which ignores all views which are marked IMPORTANT_FOR_ACCESSIBILITY_NO or IMPORTANT_FOR_ACCESSIBILITY_AUTO (and have been deemed not important by the system), in an attempt to make things less confusing or faster.
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
## Android Setup
|
||||
|
||||
To get started, you'll need to install node.js (v4 or greater). Just
|
||||
To get started, you'll need to install Node.js (v4 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, under the 'tools' directory).
|
||||
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, under the 'tools' directory).
|
||||
|
||||
Run the 'android' tool and use it to install an API Level 17 or greater.
|
||||
Run the `android` tool and use it to install an API Level 17 or greater.
|
||||
|
||||
(If you want to run Appium from source, you will also need [Apache Ant](http://ant.apache.org/) to build the bootstrap jar that Appium uses for running against Android simulators/devices.)
|
||||
|
||||
@@ -16,13 +16,12 @@ shell startup:
|
||||
|
||||
export ANDROID_HOME="/usr/local/adt/sdk"
|
||||
|
||||
Now you're set up to run Appium! If you're running Appium from source, run
|
||||
`npm install` from your Appium checkout to install all the
|
||||
dependencies.
|
||||
Now you're set up to run Appium! (If you're running Appium from source, make sure to run `npm install` from your Appium checkout to install all the
|
||||
dependencies.)
|
||||
|
||||
### Additional Setup for Older Versions of Android
|
||||
|
||||
Appium uses, and comes prepackaged with, Selendroid for running Android
|
||||
Appium uses, and comes prepackaged with, a project called [Selendroid](https://selendroid.io) for running Android
|
||||
versions 2.3 to 4.1. Appium switches to using Selendroid automatically when it
|
||||
detects older versions, but there is some additional setup required if you're
|
||||
running from source.
|
||||
@@ -44,7 +43,7 @@ See the [server documentation](/docs/en/writing-running-appium/server-args.md) f
|
||||
limitations. For more information you can check out this
|
||||
[page](/docs/en/appium-setup/android-hax-emulator.md).
|
||||
* Make sure that `hw.battery=yes` in your AVD's `config.ini`, if you want to
|
||||
run any of the Appium tests, or use any of the power commands.
|
||||
* Selendroid requires the following permission for your app:
|
||||
run any of the Appium tests, or use any of the power commands. As of Android 5.0, this is the default.
|
||||
* Selendroid requires the following permission for instrumenting your app:
|
||||
`<uses-permission android:name="android.**permission.INTERNET"/>`,
|
||||
please make sure your app has internet permission set when you are using selendroid or older versions of Android i.e. 2.3 to 4.1
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Parallel Android Tests
|
||||
|
||||
Appium provides a way for users to automate multiple Android sessions on a single machine. All it involves is starting multiple Appium servers with different flags.
|
||||
Appium provides a way for users to automate multiple Android sessions on a single machine. All it involves is starting multiple Appium servers with different flags.
|
||||
|
||||
The important flags for automating multiple Android sessions are:
|
||||
|
||||
@@ -18,13 +18,13 @@ If we had two devices with the ID's 43364 and 32456, we would start two differen
|
||||
|
||||
`node . -p 4491 -bp 2252 -U 43364`
|
||||
|
||||
As long as your Appium and Appium bootstrap ports are between 0 and 65536, all they have to be is different so that two Appium servers aren't trying to listen on the same port. Be sure that your -u flag corresponds with the correct device ID. This is how Appium knows which device to communicate with, so it must be accurate.
|
||||
As long as your Appium and Appium bootstrap ports are between 0 and 65536, all they have to be is different so that two Appium servers aren't trying to listen on the same port. Be sure that your -u flag corresponds with the correct device ID. This is how Appium knows which device to communicate with, so it must be accurate.
|
||||
|
||||
If you are using chromedriver or selendroid, set a different port for each server.
|
||||
|
||||
### Parallel iOS Tests
|
||||
|
||||
Unfortunately, running local parallel iOS tests aren't possible. Unlike Android, only one version of the iOS simulator can be launched at a time, making it run multiple tests at once.
|
||||
Unfortunately, running local parallel iOS tests isn't currently possible. Unlike Android, only one version of the iOS simulator can be launched at a time, making it run multiple tests at once.
|
||||
|
||||
If you do want to run parallel iOS tests, you need to use Sauce. Simply upload your Appium test to Sauce, and it can run as many parallel iOS or Android tests as your account allows. See more about running your tests on Sauce [here](https://docs.saucelabs.com/tutorials/appium/).
|
||||
|
||||
|
||||
@@ -9,21 +9,21 @@ make explicit the level of support and requirements for each of these.
|
||||
See [Running on OS X: iOS](running-on-osx.md) for iOS requirements and setup
|
||||
instructions.
|
||||
|
||||
* Versions: 7.1, 8.0, 8.1, 8.2, 8.3, 8.4, 9.0, 9.1 and 9.2
|
||||
* Versions: 7.1 and up
|
||||
* Devices: iPhone Simulator, iPad Simulator, and real iPhones and iPads
|
||||
* Native app support: Yes, with debug version of .app (simulator),
|
||||
or correctly-signed .ipa (real devices). Underlying support is provided by
|
||||
Apple's [UIAutomation](https://developer.apple.com/library/ios/documentation/DeveloperTools/Reference/UIAutomationRef/)
|
||||
Apple's [XCUITest](https://developer.apple.com/reference/xctest) (or [UIAutomation](https://developer.apple.com/library/ios/documentation/DeveloperTools/Reference/UIAutomationRef/) for older versions)
|
||||
framework.
|
||||
* Mobile web support: Yes, via automation of mobile Safari. For real devices,
|
||||
ios-webkit-remote-debugger is required, and automation of native aspects of
|
||||
`ios-webkit-remote-debugger` is required, and automation of native aspects of
|
||||
the Safari interface is not possible. See the [mobile web doc](/docs/en/writing-running-appium/mobile-web.md) for instructions.
|
||||
* Hybrid support: Yes. For real devices, ios-webkit-remote-debugger is
|
||||
required. See the [hybrid doc](/docs/en/advanced-concepts/hybrid.md) for instructions.
|
||||
* Support for automating multiple apps in one session: No
|
||||
* Support for automating multiple devices simultaneously: No
|
||||
* Support for automating vendor-provided or third-party apps: Only
|
||||
vendor-provided apps (Preferences, Maps, etc...), and only on the simulator
|
||||
vendor-provided apps (Preferences, Maps, etc...), and only on the simulator. For iOS 10+, you can automate the home screen as well.
|
||||
* Support for automating custom, non-standard UI controls: Minimal. You need to
|
||||
set accessibility information on the control which enables some basic
|
||||
automation.
|
||||
@@ -62,8 +62,9 @@ instructions.
|
||||
when using the Selendroid backend)
|
||||
* Support for automating custom, non-standard UI controls: No
|
||||
|
||||
### Windows Support
|
||||
### Windows Desktop Support
|
||||
|
||||
See [running on Windows](running-on-windows.md) for details
|
||||
See these docs for details:
|
||||
|
||||
* [Windows App Testing](windows-app-testing.md)
|
||||
* [Running on Windows](running-on-windows.md)
|
||||
* [Windows App Testing](/docs/en/writing-running-appium/windows-app-testing.md)
|
||||
|
||||
@@ -4,14 +4,14 @@ Appium on OS X supports iOS and Android testing.
|
||||
|
||||
### System setup (iOS)
|
||||
|
||||
* Appium requires Mac OS X 10.7 or greater. We recommend OS X 10.10.
|
||||
* Appium requires Mac OS X 10.10 or greater.
|
||||
* Make sure you have Xcode and the iOS SDK(s) installed. Xcode version 7.1 is
|
||||
recommended as earlier versions of Xcode are limited in which versions of iOS
|
||||
they can test against. See the next section for more detail.
|
||||
* You need to authorize use of the iOS Simulator. See [below](#authorizing-ios-on-the-computer).
|
||||
* If you're on Xcode 7.x, Instruments Without Delay (IWD) does not work. You can
|
||||
enable IWD (which will significantly speed up your tests) using
|
||||
[this method](/docs/en/advanced-concepts/iwd_xcode7.md)
|
||||
* If you're on Xcode 7.x and up, Instruments Without Delay (IWD) does not work.
|
||||
You can enable IWD (which will significantly speed up your tests) using [this
|
||||
method](/docs/en/advanced-concepts/iwd_xcode7.md)
|
||||
* If you're on Xcode 6, you need to launch each simulator you intend to use
|
||||
with appium in advance, and change the default to actually show the soft
|
||||
keyboard if you want sendKeys to work. You can do this by clicking on any
|
||||
@@ -23,7 +23,7 @@ Appium on OS X supports iOS and Android testing.
|
||||
a platformVersion cap of "8.0", you need to make sure that there is exactly
|
||||
one device with the name "iPhone 5s" and the 8.0 sdk in your devices list.
|
||||
Otherwise, Appium won't know which one to use.
|
||||
* In iOS8, devices each have their own setting which enables or disables
|
||||
* In iOS 8, devices each have their own setting which enables or disables
|
||||
UIAutomation. It lives in a "Developer" view in the Settings app. You need to
|
||||
verify that UIAutomaion is enabled in this view before the simulator or
|
||||
device can be automated.
|
||||
|
||||
@@ -60,6 +60,7 @@ own items in the SDK manager. Make sure you install the build-tools and platform
|
||||
* If Instruments is crashing when running against a physical device ("exited with code 253"), ensure Xcode has downloaded device symbols. Go to Window -> Devices, and it should start automatically. This is needed after iOS version upgrades.
|
||||
* If you see `iOS Simulator failed to install the application.` and the
|
||||
paths are correct, try restarting the computer.
|
||||
* Make sure your macOS keychain that holds the certificate(s) needed for building your app and the WebDriverAgent is unlocked. Especialy if you are using ssh. General symptom to look for is `codesign` failure.
|
||||
* If you have custom elements in your app, they will not be automatable by
|
||||
UIAutomation (and therefore Appium) by default. You need to set the
|
||||
accessibility status to 'enabled' on them. The way to do this in code is:
|
||||
@@ -139,11 +140,6 @@ own items in the SDK manager. Make sure you install the build-tools and platform
|
||||
* In a Safari session, if the logs indicate that the initial url cannot be entered, make sure that
|
||||
you have the software keyboard enabled. See this [discussion](https://github.com/appium/appium/issues/6440).
|
||||
|
||||
### FirefoxOS
|
||||
|
||||
* Make sure the Boot-to-Gecko simulator is up and running.
|
||||
* Make sure the simulator screen is alive and unlocked (might require restarting B2G).
|
||||
|
||||
### Let the community know
|
||||
|
||||
Once you've tried the above steps and your issue still isn't resolved,
|
||||
|
||||
@@ -81,10 +81,8 @@ have to modify your `/etc/authorization` file in one of two ways:
|
||||
`/etc/authorization` file for you:
|
||||
|
||||
```center
|
||||
sudo node_modules/.bin/authorize-ios.js
|
||||
|
||||
# alternatively
|
||||
sudo $(npm bin)/authorize-ios
|
||||
npm install -g authorize-ios
|
||||
sudo authorize-ios
|
||||
```
|
||||
|
||||
At this point, run:
|
||||
|
||||
@@ -14,3 +14,4 @@
|
||||
* [instruments-without-delay](https://github.com/facebook/instruments-without-delay)
|
||||
* [deviceconsole](https://github.com/rpetrich/deviceconsole)
|
||||
* [WinAppDriver](http://github.com/Microsoft/WinAppDriver)
|
||||
* [WebDriverAgent](https://github.com/facebook/webdriveragent)
|
||||
|
||||
@@ -30,6 +30,37 @@ _development_ questions, not _usage_ questions or bug reports. Usage questions
|
||||
belong on [discuss.appium.io](https://discuss.appium.io). The GitHub issue
|
||||
tracker is for bug reports and feature requests only.
|
||||
|
||||
### Agile Development Workflow
|
||||
|
||||
The Appium team runs development according to a very lightweight version of
|
||||
SCRUM. Every two weeks we begin a new "sprint", or a period of time in which we
|
||||
have decided what we want to accomplish. Anyone familiar with the Appium
|
||||
codebase is welcome to attend our sprint planning and participate as a SCRUM
|
||||
team member for that sprint. No long-term commitments required! During the
|
||||
sprint, we update each other with daily progress in the `#standup` room in our
|
||||
[Appium Slack Group](https://appium.slack.com) (there are no real-time daily
|
||||
standups). At the end of the sprint, to celebrate our accomplishments and
|
||||
reflect on how things went, we hold a "retrospective", which might result in
|
||||
a list of things we can try differently or do better next time around.
|
||||
|
||||
Ultimately, the goal is to time an Appium release at the end of each sprint, so
|
||||
every two weeks. We're not quite there, but hopefully we will be soon.
|
||||
|
||||
Current meeting times:
|
||||
* Sprint Planning: every other Monday from 10:00 AM - 10:45 AM (Pacific Time)
|
||||
* Sprint Retrospective: every other _other_ Friday from 1:00 PM - 1:30 PM (Pacific Time)
|
||||
|
||||
We hold meetings using [Zoom](https://zoom.us) video chat.
|
||||
|
||||
For project management, we use the [ZenHub](http://zenhub.com) browser plugin,
|
||||
which adds various features like Kanban boards and Epics to the GitHub
|
||||
interface. To fully participate in Appium SCRUM, you'll need to have this
|
||||
browser plugin installed.
|
||||
|
||||
If you are interested in participating a sprint, ping `@jlipps` or `@isaac` in
|
||||
the Appium Slack Group, or DM `@jlipps` on Twitter, and we'll share how to join
|
||||
the video chat for the next sprint.
|
||||
|
||||
### Architecture
|
||||
|
||||
Appium is primarily a collection of [node.js](http://nodejs.org) packages that
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Appium gulp commands
|
||||
|
||||
[Gulp](http://gulpjs.com) is like make for Node.js! We use it to automate all
|
||||
[Gulp](http://gulpjs.com) is like `make` for Node.js! We use it to automate all
|
||||
kinds of appium dev tasks. Here's what you can do:
|
||||
|
||||
|Task|Description|
|
||||
|
||||
@@ -210,7 +210,7 @@ driver.open_notifications()
|
||||
|
||||
```ruby
|
||||
# ruby
|
||||
openNotifications
|
||||
open_notifications
|
||||
```
|
||||
|
||||
```csharp
|
||||
@@ -434,7 +434,7 @@ autoLaunch=false.
|
||||
|
||||
```ruby
|
||||
# ruby
|
||||
launch
|
||||
launch_app
|
||||
```
|
||||
|
||||
```python
|
||||
@@ -473,7 +473,7 @@ Reset the app.
|
||||
|
||||
```ruby
|
||||
# ruby
|
||||
reset
|
||||
driver.reset
|
||||
```
|
||||
|
||||
```python
|
||||
@@ -630,7 +630,7 @@ Get the app's strings.
|
||||
|
||||
```ruby
|
||||
# ruby
|
||||
strings = app_strings
|
||||
app_strings
|
||||
```
|
||||
|
||||
```python
|
||||
|
||||
@@ -1,245 +0,0 @@
|
||||
# Apple XCUITest
|
||||
|
||||
Xcode 7 introduces [new UI testing features](https://developer.apple.com/videos/play/wwdc2015/406/). Moving forward, [Appium iOS Driver](https://github.com/appium/appium-ios-driver) will leverage this framework, replacing UI Automation. While there are no official docs, @joemasilotti has created [some handy unofficial docs](http://masilotti.com/xctest-documentation/index.html) by pulling out comments from the header files.
|
||||
|
||||
## Launching the App (XCUIApplication)
|
||||
- ##### – launch
|
||||
|
||||
Launches the application. This call is synchronous and when it returns the application is launched
|
||||
and ready to handle user events. Any failure in the launch sequence is reported as a test failure
|
||||
and halts the test at this point. If the application is already running, this call will first
|
||||
terminate the existing instance to ensure clean state of the launched instance.
|
||||
|
||||
- ##### – terminate
|
||||
|
||||
Terminates any running instance of the application. If the application has an existing debug session
|
||||
via Xcode, the termination is implemented as a halt via that debug connection. Otherwise, a SIGKILL
|
||||
is sent to the process.
|
||||
|
||||
- ##### launchArguments
|
||||
|
||||
The arguments that will be passed to the application on launch. If not modified, these are the
|
||||
arguments that Xcode will pass on launch. Those arguments can be changed, added to, or removed.
|
||||
Unlike NSTask, it is legal to modify these arguments after the application has been launched. These
|
||||
changes will not affect the current launch session, but will take effect the next time the application
|
||||
is launched.
|
||||
|
||||
- ##### launchEnvironment
|
||||
|
||||
The environment that will be passed to the application on launch. If not modified, this is the
|
||||
environment that Xcode will pass on launch. Those variables can be changed, added to, or removed.
|
||||
Unlike NSTask, it is legal to modify the environment after the application has been launched. These
|
||||
changes will not affect the current launch session, but will take effect the next time the application
|
||||
is launched.
|
||||
|
||||
## Accessing the Device (XCUIDevice)
|
||||
- ##### + sharedDevice
|
||||
|
||||
The current device.
|
||||
|
||||
- ##### orientation
|
||||
|
||||
The orientation of the device.
|
||||
|
||||
- ##### – pressButton:
|
||||
|
||||
Simulates the user pressing a physical button.
|
||||
|
||||
## Querying for Elements (XCUIElementQuery)
|
||||
- ##### element
|
||||
|
||||
Returns an element that will use the query for resolution.
|
||||
|
||||
- ##### count
|
||||
|
||||
Evaluates the query at the time it is called and returns the number of matches found.
|
||||
|
||||
- ##### – elementAtIndex:
|
||||
|
||||
Returns an element that will resolve to the index into the query’s result set.
|
||||
|
||||
- ##### – elementBoundByIndex:
|
||||
|
||||
Returns an element that will use the index into the query’s results to determine which underlying accessibility element it is matched with.
|
||||
|
||||
- ##### – elementMatchingPredicate:
|
||||
|
||||
Returns an element that matches the predicate. The predicate will be evaluated against objects of type idXCUIElementAttributes.
|
||||
|
||||
- ##### – elementMatchingType:identifier:
|
||||
|
||||
Returns an element that matches the type and identifier.
|
||||
|
||||
- ##### – objectForKeyedSubscript:
|
||||
|
||||
Keyed subscripting is implemented as a shortcut for matching an identifier only. For example, app.descendants[“Foo”] -> XCUIElement.
|
||||
|
||||
- ##### allElementsBoundByAccessibilityElement
|
||||
|
||||
Immediately evaluates the query and returns an array of elements bound to the resulting accessibility elements.
|
||||
|
||||
- ##### allElementsBoundByIndex
|
||||
|
||||
Immediately evaluates the query and returns an array of elements bound by the index of each result.
|
||||
|
||||
- ##### – descendantsMatchingType:
|
||||
|
||||
Returns a new query that finds the descendants of all the elements found by the receiver.
|
||||
|
||||
- ##### – childrenMatchingType:
|
||||
|
||||
Returns a new query that finds the direct children of all the elements found by the receiver.
|
||||
|
||||
- ##### – matchingPredicate:
|
||||
|
||||
Returns a new query that applies the specified attributes or predicate to the receiver. The predicate will be evaluated against objects of type idXCUIElementAttributes.
|
||||
|
||||
- ##### – matchingType:identifier:
|
||||
|
||||
- ##### – matchingIdentifier:
|
||||
|
||||
- ##### – containingPredicate:
|
||||
|
||||
Returns a new query for finding elements that contain a descendant matching the specification. The predicate will be evaluated against objects of type idXCUIElementAttributes.
|
||||
|
||||
- ##### – containingType:identifier:
|
||||
|
||||
- ##### debugDescription
|
||||
|
||||
@discussion
|
||||
Provides debugging information about the query. The data in the string will vary based on the time
|
||||
at which it is captured, but it may include any of the following as well as additional data:
|
||||
• A description of each step of the query.
|
||||
• Information about the inputs and matched outputs of each step of the query.
|
||||
This data should be used for debugging only - depending on any of the data as part of a test is unsupported.
|
||||
|
||||
## Interacting with Elements (XCUIElement)
|
||||
### XCUIElementEventSynthesis Methods
|
||||
- ##### – typeText:
|
||||
|
||||
Types a string into the element. The element or a descendant must have keyboard focus; otherwise an
|
||||
error is raised.
|
||||
|
||||
- ##### – tap
|
||||
|
||||
Sends a tap event to a hittable point computed for the element.
|
||||
|
||||
- ##### – doubleTap
|
||||
|
||||
Sends a double tap event to a hittable point computed for the element.
|
||||
|
||||
- ##### – twoFingerTap
|
||||
|
||||
Sends a two finger tap event to a hittable point computed for the element.
|
||||
|
||||
- ##### – tapWithNumberOfTaps:numberOfTouches:
|
||||
|
||||
Sends one or more taps with one of more touch points.
|
||||
|
||||
- ##### – pressForDuration:
|
||||
|
||||
Sends a long press gesture to a hittable point computed for the element, holding for the specified duration.
|
||||
|
||||
- ##### – pressForDuration:thenDragToElement:
|
||||
|
||||
Initiates a press-and-hold gesture that then drags to another element, suitable for table cell reordering and similar operations.
|
||||
@param duration
|
||||
Duration of the initial press-and-hold.
|
||||
@param otherElement
|
||||
The element to finish the drag gesture over. In the example of table cell reordering, this would be the reorder element of the destination row.
|
||||
|
||||
- ##### – swipeUp
|
||||
|
||||
Sends a swipe-up gesture.
|
||||
|
||||
- ##### – swipeDown
|
||||
|
||||
Sends a swipe-down gesture.
|
||||
|
||||
- ##### – swipeLeft
|
||||
|
||||
Sends a swipe-left gesture.
|
||||
|
||||
- ##### – swipeRight
|
||||
|
||||
Sends a swipe-right gesture.
|
||||
|
||||
- ##### – pinchWithScale:velocity:
|
||||
|
||||
Sends a pinching gesture with two touches.
|
||||
|
||||
- ##### – rotate:withVelocity:
|
||||
|
||||
Sends a rotation gesture with two touches.
|
||||
|
||||
### XCUIElementTypeSlider Methods
|
||||
- ##### – adjustToNormalizedSliderPosition:
|
||||
|
||||
Manipulates the UI to change the displayed value of the slider to one based on a normalized position. 0 corresponds to the minimum value of the slider, 1 corresponds to its maximum value. The adjustment is a “best effort” to move the indicator to the desired position; absolute fidelity is not guaranteed.
|
||||
|
||||
- ##### normalizedSliderPosition
|
||||
|
||||
Returns the position of the slider’s indicator as a normalized value where 0 corresponds to the minimum value of the slider and 1 corresponds to its maximum value.
|
||||
|
||||
### XCUIElementTypePickerWheel Methods
|
||||
- ##### – adjustToPickerWheelValue:
|
||||
|
||||
Changes the displayed value for the picker wheel. Will generate a test failure if the specified value is not available.
|
||||
|
||||
### Other Methods
|
||||
- ##### exists
|
||||
|
||||
Test to determine if the element exists.
|
||||
|
||||
- ##### hittable
|
||||
|
||||
Whether or not a hit point can be computed for the element for the purpose of synthesizing events.
|
||||
|
||||
- ##### – descendantsMatchingType:
|
||||
|
||||
Returns a query for all descendants of the element matching the specified type.
|
||||
|
||||
- ##### – childrenMatchingType:
|
||||
|
||||
Returns a query for direct children of the element matching the specified type.
|
||||
|
||||
- ##### – coordinateWithNormalizedOffset:
|
||||
|
||||
Creates and returns a new coordinate that will compute its screen point by adding the offset multiplied by the size of the element’s frame to the origin of the element’s frame.
|
||||
|
||||
- ##### debugDescription
|
||||
|
||||
@discussion
|
||||
Provides debugging information about the element. The data in the string will vary based on the
|
||||
time at which it is captured, but it may include any of the following as well as additional data:
|
||||
• Values for the elements attributes.
|
||||
• The entire tree of descendants rooted at the element.
|
||||
• The element’s query.
|
||||
This data should be used for debugging only - depending on any of the data as part of a test is unsupported.
|
||||
|
||||
## Using Coordinates (XCUICoordinate)
|
||||
- ##### – init
|
||||
|
||||
Coordinates are never instantiated directly. Instead, they are created by elements or by other coordinates.
|
||||
|
||||
- ##### referencedElement
|
||||
|
||||
The element that the coordinate is based on, either directly or via the coordinate from which it was derived.
|
||||
|
||||
- ##### screenPoint
|
||||
|
||||
The dynamically computed value of the coordinate’s location on screen. Note that this value is dependent on the current frame of the referenced element; if the element’s frame changes, so will the value returned by this property. If the referenced element does exist when this is called, it will fail the test; check the referenced element’s exists property if the element may not be present.
|
||||
|
||||
- ##### – coordinateWithOffset:
|
||||
|
||||
Creates a new coordinate with an absolute offset in points from the original coordinate.
|
||||
|
||||
- ##### – tap
|
||||
|
||||
- ##### – doubleTap
|
||||
|
||||
- ##### – pressForDuration:
|
||||
|
||||
- ##### – pressForDuration:thenDragToCoordinate:
|
||||
|
||||
- ##### – hover
|
||||
@@ -62,6 +62,7 @@
|
||||
|`recreateChromeDriverSessions`| Kill ChromeDriver session when moving to a non-ChromeDriver webview. Defaults to `false` | `true` or `false`|
|
||||
|`nativeWebScreenshot`| In a web context, use native (adb) method for taking a screenshot, rather than proxying to ChromeDriver. Defaults to `false` | `true` or `false`|
|
||||
|`androidScreenshotPath`| The name of the directory on the device in which the screenshot will be put. Defaults to `/data/local/tmp` |e.g. `/sdcard/screenshots/`|
|
||||
|`autoGrantPermissions`|Have Appium automatically determine which permissions your app requires and grant them to the app on install. Defaults to `false`|`true` or `false`|
|
||||
|
||||
### iOS Only
|
||||
|
||||
@@ -75,8 +76,8 @@
|
||||
|`launchTimeout`| Amount of time in ms to wait for instruments before assuming it hung and failing the session|e.g. `20000`|
|
||||
|`locationServicesEnabled`| (Sim-only) Force location services to be either on or off. Default is to keep current sim setting.|`true` or `false`|
|
||||
|`locationServicesAuthorized`| (Sim-only) Set location services to be authorized or not authorized for app via plist, so that location services alert doesn't pop up. Default is to keep current sim setting. Note that if you use this setting you MUST also use the `bundleId` capability to send in your app's bundle ID.|`true` or `false`|
|
||||
|`autoAcceptAlerts`| Accept all iOS alerts automatically if they pop up. This includes privacy access permission alerts (e.g., location, contacts, photos). Default is false.|`true` or `false`|
|
||||
|`autoDismissAlerts`| Dismiss all iOS alerts automatically if they pop up. This includes privacy access permission alerts (e.g., location, contacts, photos). Default is false.|`true` or `false`|
|
||||
|`autoAcceptAlerts`| Accept all iOS alerts automatically if they pop up. This includes privacy access permission alerts (e.g., location, contacts, photos). Default is false. Does not work on `XCUITest`-based tests.|`true` or `false`|
|
||||
|`autoDismissAlerts`| Dismiss all iOS alerts automatically if they pop up. This includes privacy access permission alerts (e.g., location, contacts, photos). Default is false. Does not work on `XCUITest`-based tests.|`true` or `false`|
|
||||
|`nativeInstrumentsLib`| Use native intruments lib (ie disable instruments-without-delay).|`true` or `false`|
|
||||
|`nativeWebTap`| (Sim-only) Enable "real", non-javascript-based web taps in Safari. Default: `false`. Warning: depending on viewport size/ratio this might not accurately tap an element|`true` or `false`|
|
||||
|`safariInitialUrl`| (Sim-only) (>= 8.1) Initial safari url, default is a local welcome page | e.g. `https://www.github.com` |
|
||||
@@ -93,6 +94,8 @@
|
||||
|`waitForAppScript`| The ios automation script used to determined if the app has been launched, by default the system wait for the page source not to be empty. The result must be a boolean |e.g. `true;`, `target.elements().length > 0;`, `$.delay(5000); true;` |
|
||||
|`webviewConnectRetries`| Number of times to send connection message to remote debugger, to get webview. Default: `8` |e.g., `12`|
|
||||
|`appName`| The display name of the application under test. Used to automate backgrounding the app in iOS 9+.|e.g., `UICatalog`|
|
||||
|`customSSLCert`|(Sim/Emu-only) Add an SSL certificate to simulator. | e.g. <br/>`-----BEGIN CERTIFICATE-----MIIFWjCCBEKg...`<br/>`-----END CERTIFICATE-----`|
|
||||
|
||||
|
||||
### iOS Only, using XCUITest
|
||||
|
||||
@@ -103,11 +106,15 @@
|
||||
|`processArguments`|Process arguments and environment which will be sent to the WebDriverAgent server.|`{ args: ["a", "b", "c"] , env: { "a": "b", "c": "d" } }` or `'{"args": ["a", "b", "c"], "env": { "a": "b", "c": "d" }}'`|
|
||||
|`wdaLocalPort`|This value if specified, will be used to forward traffic from Mac host to real ios devices over USB. Default value is same as port number used by WDA on device.|e.g., `8100`|
|
||||
|`showXcodeLog`|Whether to display the output of the Xcode command used to run the tests. If this is `true`, there will be **lots** of extra logging at startup. Defaults to `false`|e.g., `true`|
|
||||
|`realDeviceLogger`|Device logger for real devices. It could be path to `deviceconsole` (installed with `npm install deviceconsole`, a compiled binary named `deviceconsole` will be added to `./node_modules/deviceconsole/`) or `idevicesyslog` (comes with libimobiledevice). Defaults to `idevicesyslog`|`idevicesyslog`, `/abs/path/to/deviceconsole`|
|
||||
|`iosInstallPause`|Time in milliseconds to pause between installing the application and starting WebDriverAgent on the device. Used particularly for larger applications. Defaults to `0`|e.g., `8000`|
|
||||
|`xcodeConfigFile`|Full path to an optional Xcode configuration file that specifies the code signing identity and team for running the WebDriverAgent on the real device.|e.g., `/path/to/myconfig.xcconfig`|
|
||||
|`keychainPath`|Full path to the private development key exported from the system keychain. Used in conjunction with `keychainPassword` when testing on real devices.|e.g., `/path/to/MyPrivateKey.p12`|
|
||||
|`keychainPassword`|Password for unlocking keychain specified in `keychainPath`.|e.g., `super awesome password`|
|
||||
|`scaleFactor`|Simulator scale factor. This is useful to have if the default resolution of simulated device is greater than the actual display resolution. So you can scale the simulator to see the whole device screen without scrolling. |Acceptable values are: `'1.0', '0.75', '0.5', '0.33' and '0.25'`. The value should be a string.|
|
||||
|`preventWDAAttachments`|Sets read only permissons to Attachments subfolder of WebDriverAgent root inside Xcode's DerivedData. This is necessary to prevent XCTest framework from creating tons of unnecessary screenshots and logs, which are impossible to shutdown using programming interfaces provided by Apple.|Setting the capability to `true` will set Posix permissions of the folder to `555` and `false` will reset them back to `755`|
|
||||
|`webDriverAgentUrl`|If provided, Appium will connect to an existing WebDriverAgent instance at this URL instead of starting a new one.|e.g., `http://localhost:8100`|
|
||||
|`useNewWDA`|If `true`, forces uninstall of any existing WebDriverAgent app on device. This can provide stability in some situations. Defaults to `false`.|e.g., `true`|
|
||||
|`wdaLaunchTimeout`|Time, in ms, to wait for WebDriverAgewnt to be pingable. Defaults to 60000ms.|e.g., `30000`|
|
||||
|
||||
### You.i Engine Only
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## The --default-capabilities flag
|
||||
|
||||
Appium 1.5 does away with most CLI flags; the remainder can be converted into JSON and made part of the `--default-capabilities` flag. For example:
|
||||
Appium 1.5 does away with most CLI flags that existed previously; the remainder can be converted into JSON and made part of the `--default-capabilities` flag. For example:
|
||||
|
||||
```
|
||||
# raw JSON as an argument
|
||||
@@ -28,13 +28,13 @@ Appium 1.5 does away with most CLI flags; the remainder can be converted into JS
|
||||
| --udid | udid |
|
||||
| --orientation | orientation |
|
||||
| --no-reset | noReset |
|
||||
| --full-reset | rullReset |
|
||||
| --full-reset | fullReset |
|
||||
| --app-pkg | appPackage |
|
||||
| --app-activity | appActivity |
|
||||
| --app-wait-package | appWaitPackage |
|
||||
| --app-wait-activity | appWaitActivity |
|
||||
| --device-ready-timeout | deviceReadyTimeout |
|
||||
| --android-coverage | androidCoverage |
|
||||
| --android-coverage | androidCoverage |
|
||||
| --avd | avd |
|
||||
| --avd-args | avdArgs |
|
||||
| --use-keystore | useKeystore |
|
||||
|
||||
@@ -9,7 +9,7 @@ with certain constraints)
|
||||
Appium additionally supports some of the [Mobile JSON Wire Protocol](https://github.com/SeleniumHQ/mobile-spec/blob/master/spec-draft.md) locator strategies
|
||||
|
||||
* `-ios uiautomation`: a string corresponding to a recursive element search
|
||||
using the [UIAutomation library](ios_predicate.md) (iOS-only)
|
||||
using the [UIAutomation library](ios_predicate.md) (iOS 9.3 and below only)
|
||||
* `-android uiautomator`: a string corresponding to a recursive element
|
||||
search using the [UiAutomator Api](uiautomator_uiselector.md) (Android-only)
|
||||
* `accessibility id`: a string corresponding to a recursive element search
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
## iOS Predicate
|
||||
|
||||
*NOTE*: iOS predicates are usable in iOS 9.3 and below using the `-ios uiautomation` locator strategy and they are usable in iOS 10 and above using the `-ios predicate string` locator strategy
|
||||
|
||||
It is worth looking at *'-ios uiautomation'* search strategy with **Predicates**.
|
||||
[UIAutomation JavaScript API](https://developer.apple.com/library/ios/documentation/DeveloperTools/Reference/UIAutomationRef/) has following methods which can are very useful.
|
||||
|
||||
@@ -11,11 +13,18 @@ It is worth looking at *'-ios uiautomation'* search strategy with **Predicates**
|
||||
Native JS search strategy (powered by Apple) provides much more flexibility and is like Xpath.
|
||||
**[Predicates](https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Predicates/AdditionalChapters/Introduction.html)** can be used to restrict an elements set to select only those ones for which some condition is true.
|
||||
|
||||
For example:
|
||||
'-ios uiautomation' example:
|
||||
|
||||
```java
|
||||
// java
|
||||
appiumDriver.findElementsByIosUIAutomation("collectionViews()[0].cells().withPredicate(\"ANY staticTexts.isVisible == TRUE\")")
|
||||
appiumDriver.findElementsByIosUIAutomation("collectionViews()[0].cells().withPredicate(\"ANY staticTexts.isVisible == TRUE\")");
|
||||
```
|
||||
|
||||
'-ios predicate string' example:
|
||||
|
||||
```java
|
||||
// java
|
||||
appiumDriver.findElementsByIosNsPredicate("isWDVisible == 1");
|
||||
```
|
||||
|
||||
\- will select only those ```UIACollectionCell``` elements that have visible ```UIAStaticText``` child elements, and themselves are childs of 1st ```UIACollectionView``` element that should be located under the main app window. Here ```staticTexts()``` and ```isVisible()``` are methods available in ```UIAElementArray``` and ```UIAElement``` classes respectively. **Note that ```UIAElementArray``` numbering begins with ```0``` unlike Xpath where indexes counting starts from ```1```**
|
||||
|
||||
@@ -60,13 +60,15 @@ capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "iPhone Simulator")
|
||||
|
||||
### Mobile Safari on a Real iOS Device
|
||||
|
||||
We use the [SafariLauncher
|
||||
App](https://github.com/snevesbarros/SafariLauncher) to launch Safari and run
|
||||
tests against mobile Safari. Once Safari has been launched the Remote Debugger
|
||||
automatically connects using the
|
||||
[ios-webkit-debug-proxy](https://github.com/google/ios-webkit-debug-proxy). When
|
||||
working with ios-webkit-debug-proxy, you have to trust the machine before you can
|
||||
can run tests against your iOS device.
|
||||
For iOS 9.3 and below (pre-XCUITest), we use the [SafariLauncher
|
||||
App](https://github.com/snevesbarros/SafariLauncher) app to launch Safari and
|
||||
run tests against mobile Safari. This is because Safari is an app that is owned
|
||||
by Apple, and Instruments cannot launch it on real devices. Once Safari has
|
||||
been launched by SafariLauncher, the Remote Debugger automatically connects
|
||||
using the
|
||||
[ios-webkit-debug-proxy](https://github.com/google/ios-webkit-debug-proxy).
|
||||
When working with ios-webkit-debug-proxy, you have to trust the machine before
|
||||
you can can run tests against your iOS device.
|
||||
|
||||
For instruction on how to install and run ios-webkit-debugger-proxy see [iOS webKit debug proxy](/docs/en/advanced-concepts/ios-webkit-debug-proxy.md) documentation.
|
||||
|
||||
|
||||
@@ -275,8 +275,6 @@ writing your scripts for older devices or hybrid apps.
|
||||
|
||||
### Running your test app with Appium (Windows)
|
||||
|
||||
Ensure that Appium is listening
|
||||
Simply ensure that Appium is listening, and run your test with your test runner of choice.
|
||||
|
||||
Deploy your test from your test runner of choice
|
||||
|
||||
See our [samples](https://github.com/Microsoft/WinAppDriver/tree/master/Samples) for details
|
||||
See our [samples](https://github.com/Microsoft/WinAppDriver/tree/master/Samples) for details.
|
||||
|
||||
@@ -105,7 +105,7 @@ allows you to do what you wanted to do with one of these views, namely, scroll
|
||||
it!
|
||||
|
||||
|
||||
**Scrolling**
|
||||
**Scrolling<a name="scrolling">**
|
||||
|
||||
|
||||
To allow access to this special feature, we override the `execute` or
|
||||
@@ -117,7 +117,7 @@ To scroll, pass direction in which you intend to scroll as parameter.
|
||||
|
||||
```javascript
|
||||
// javascript
|
||||
driver.execute("mobile: scroll", [{direction: 'down'}])
|
||||
driver.execute('mobile: scroll', {direction: 'down'})
|
||||
```
|
||||
|
||||
```java
|
||||
@@ -154,7 +154,7 @@ Sample to scroll using direction and element.
|
||||
|
||||
```javascript
|
||||
// javascript
|
||||
driver.execute("mobile: scroll", [{direction: 'down', element: element.value}]);
|
||||
driver.execute('mobile: scroll', {direction: 'down', element: element.value.ELEMENT});
|
||||
```
|
||||
|
||||
```java
|
||||
@@ -189,6 +189,14 @@ $params = array(array('direction' => 'down', 'element' => element.GetAttribute("
|
||||
$driver->executeScript("mobile: scroll", $params);
|
||||
```
|
||||
|
||||
**Swiping**
|
||||
|
||||
This is an XCUITest driver specific method that is similar to scrolling (for reference, see
|
||||
https://developer.apple.com/reference/xctest/xcuielement).
|
||||
|
||||
This method has the same API as [Scrolling](#scrolling), just replace "mobile: scroll"
|
||||
with "mobile: swipe"
|
||||
|
||||
**Automating Sliders**
|
||||
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ To test a UWP app, you can use any Selenium supported language and simply specif
|
||||
// Launch the AlarmClock app
|
||||
DesiredCapabilities appCapabilities = new DesiredCapabilities();
|
||||
appCapabilities.SetCapability("app", "Microsoft.WindowsAlarms_8wekyb3d8bbwe!App");
|
||||
AlarmClockSession = new IOSDriver<IOSElement>(new Uri("http://127.0.0.1:4723"), appCapabilities);
|
||||
AlarmClockSession = new WindowsDriver<WindowsElement>(new Uri("http://127.0.0.1:4723"), appCapabilities);
|
||||
// Control the AlarmClock app
|
||||
AlarmClockSession.FindElementByAccessibilityId("AddAlarmButton").Click();
|
||||
AlarmClockSession.FindElementByAccessibilityId("AlarmNameTextBox").Clear();
|
||||
@@ -38,7 +38,7 @@ To test a classic Windows app, you can also use any Selenium supported language
|
||||
// Launch Notepad
|
||||
DesiredCapabilities appCapabilities = new DesiredCapabilities();
|
||||
appCapabilities.SetCapability("app", @"C:\Windows\System32\notepad.exe");
|
||||
NotepadSession = new IOSDriver<IOSElement>(new Uri("http://127.0.0.1:4723"), appCapabilities);
|
||||
NotepadSession = new WindowsDriver<WindowsElement>(new Uri("http://127.0.0.1:4723"), appCapabilities);
|
||||
// Control the AlarmClock app
|
||||
NotepadSession.FindElementByClassName("Edit").SendKeys("This is some text");
|
||||
```
|
||||
|
||||
+4
-1
@@ -1,4 +1,5 @@
|
||||
/* eslint no-console:0 */
|
||||
/* eslint-disable promise/prefer-await-to-callbacks */
|
||||
"use strict";
|
||||
|
||||
// turn all logging on since we have tests that rely on npmlog logs actually
|
||||
@@ -32,10 +33,12 @@ gulp.task('fixShrinkwrap', function (done) {
|
||||
boilerplate({
|
||||
build: 'appium',
|
||||
jscs: false,
|
||||
jshint: false,
|
||||
test: {
|
||||
files: ['${testDir}/**/*-specs.js']
|
||||
},
|
||||
extraPrepublishTasks: ['fixShrinkwrap'],
|
||||
preCommitTasks: ['eslint', 'once'],
|
||||
});
|
||||
|
||||
// generates server arguments readme
|
||||
@@ -66,7 +69,7 @@ gulp.task('docs', ['transpile'], function () {
|
||||
}
|
||||
|
||||
// handle empty objects
|
||||
if (JSON.stringify(argOpts.defaultValue) === '{}'){
|
||||
if (JSON.stringify(argOpts.defaultValue) === '{}') {
|
||||
argOpts.defaultValue = '{}';
|
||||
}
|
||||
|
||||
|
||||
+57
-17
@@ -96,6 +96,25 @@ class AppiumDriver extends BaseDriver {
|
||||
throw new Error(`${msg} Please check your desired capabilities.`);
|
||||
}
|
||||
|
||||
getDriverVersion (driver) {
|
||||
const NAME_DRIVER_MAP = {
|
||||
SelendroidDriver: 'appium-selendroid-driver',
|
||||
AndroidUiautomator2Driver: 'appium-uiautomator2-driver',
|
||||
XCUITestDriver: 'appium-xcuitest-driver',
|
||||
YouiEngineDriver: 'appium-youiengine-driver',
|
||||
FakeDriver: 'appium-fake-driver',
|
||||
AndroidDriver: 'appium-android-driver',
|
||||
IosDriver: 'appium-ios-driver',
|
||||
WindowsDriver: 'appium-windows-driver',
|
||||
};
|
||||
if (!NAME_DRIVER_MAP[driver.name]) {
|
||||
log.warn(`Unable to get version of driver '${driver.name}'`);
|
||||
return;
|
||||
}
|
||||
let {version} = require(`${NAME_DRIVER_MAP[driver.name]}/package.json`);
|
||||
return version;
|
||||
}
|
||||
|
||||
async getStatus () {
|
||||
let config = await getAppiumConfig();
|
||||
let gitSha = config['git-sha'];
|
||||
@@ -114,16 +133,23 @@ class AppiumDriver extends BaseDriver {
|
||||
return sessions;
|
||||
}
|
||||
|
||||
async createSession (caps, reqCaps) {
|
||||
caps = _.defaults(_.clone(caps), this.args.defaultCapabilities);
|
||||
let InnerDriver = this.getDriverForCaps(caps);
|
||||
let curSessions;
|
||||
log.info(`Creating new ${InnerDriver.name} session`);
|
||||
printNewSessionAnnouncement (driver, caps) {
|
||||
let driverVersion = this.getDriverVersion(driver);
|
||||
let introString = driverVersion ?
|
||||
`Creating new ${driver.name} (v${driverVersion}) session` :
|
||||
`Creating new ${driver.name} session`;
|
||||
log.info(introString);
|
||||
log.info('Capabilities:');
|
||||
util.inspect(caps);
|
||||
for (let [cap, value] of _.toPairs(caps)) {
|
||||
log.info(` ${cap}: ${util.inspect(value)}`);
|
||||
}
|
||||
}
|
||||
|
||||
async createSession (caps, reqCaps) {
|
||||
caps = _.defaults(_.clone(caps), this.args.defaultCapabilities);
|
||||
let InnerDriver = this.getDriverForCaps(caps);
|
||||
this.printNewSessionAnnouncement(InnerDriver, caps);
|
||||
|
||||
// sessionOverride server flag check
|
||||
// this will need to be re-thought when we go to multiple session support
|
||||
@@ -140,6 +166,7 @@ class AppiumDriver extends BaseDriver {
|
||||
}
|
||||
}
|
||||
|
||||
let curSessions;
|
||||
try {
|
||||
curSessions = this.curSessionDataForDriver(InnerDriver);
|
||||
} catch (e) {
|
||||
@@ -150,18 +177,11 @@ class AppiumDriver extends BaseDriver {
|
||||
let [innerSessionId, dCaps] = await d.createSession(caps, reqCaps, curSessions);
|
||||
this.sessions[innerSessionId] = d;
|
||||
|
||||
// Remove the session on unexpected shutdown, so that we are in a position
|
||||
// to open another session later on.
|
||||
// TODO: this should be removed and replaced by a onShutdown callback.
|
||||
d.onUnexpectedShutdown
|
||||
.then(() => { throw new Error('Unexpected shutdown'); })
|
||||
.catch(B.CancellationError, () => {})
|
||||
.catch((err) => {
|
||||
log.warn(`Closing session, cause was '${err.message}'`);
|
||||
log.info(`Removing session ${innerSessionId} from our master session list`);
|
||||
delete this.sessions[innerSessionId];
|
||||
})
|
||||
.done();
|
||||
// this is an async function but we don't await it because it handles
|
||||
// an out-of-band promise which is fulfilled if the inner driver
|
||||
// unexpectedly shuts down
|
||||
this.attachUnexpectedShutdownHandler(d, innerSessionId);
|
||||
|
||||
|
||||
log.info(`New ${InnerDriver.name} session created successfully, session ` +
|
||||
`${innerSessionId} added to master session list`);
|
||||
@@ -172,6 +192,26 @@ class AppiumDriver extends BaseDriver {
|
||||
return [innerSessionId, dCaps];
|
||||
}
|
||||
|
||||
async attachUnexpectedShutdownHandler (driver, innerSessionId) {
|
||||
// Remove the session on unexpected shutdown, so that we are in a position
|
||||
// to open another session later on.
|
||||
// TODO: this should be removed and replaced by a onShutdown callback.
|
||||
try {
|
||||
await driver.onUnexpectedShutdown; // this is a cancellable promise
|
||||
// if we get here, we've had an unexpected shutdown, so error
|
||||
throw new Error('Unexpected shutdown');
|
||||
} catch (e) {
|
||||
if (e instanceof B.CancellationError) {
|
||||
// if we cancelled the unexpected shutdown promise, that means we
|
||||
// no longer care about it, and can safely ignore it
|
||||
return;
|
||||
}
|
||||
log.warn(`Closing session, cause was '${e.message}'`);
|
||||
log.info(`Removing session ${innerSessionId} from our master session list`);
|
||||
delete this.sessions[innerSessionId];
|
||||
}
|
||||
}
|
||||
|
||||
curSessionDataForDriver (InnerDriver) {
|
||||
let data = _.values(this.sessions)
|
||||
.filter((s) => s.constructor.name === InnerDriver.name)
|
||||
|
||||
@@ -42,6 +42,18 @@ async function postRequest (data, addr, port) {
|
||||
logger.errorAndThrow(`Syntax error in node configuration file: ${err.message}`);
|
||||
}
|
||||
|
||||
// Move Selenium 3 configuration properties to configuration object
|
||||
if (!jsonObject.hasOwnProperty('configuration')) {
|
||||
let configuration = {};
|
||||
for (var property in jsonObject) {
|
||||
if (jsonObject.hasOwnProperty(property) && property !== 'capabilities') {
|
||||
configuration[property] = jsonObject[property];
|
||||
delete jsonObject[property];
|
||||
}
|
||||
}
|
||||
jsonObject.configuration = configuration;
|
||||
}
|
||||
|
||||
// if the node config does not have the appium/webdriver url, host, and port,
|
||||
// automatically add it based on how appium was initialized
|
||||
// otherwise, we will take whatever the user setup
|
||||
|
||||
+1
-1
@@ -53,7 +53,7 @@ function timestamp () {
|
||||
// having to create 2 loggers.
|
||||
function applyStripColorPatch (transport) {
|
||||
let _log = transport.log.bind(transport);
|
||||
transport.log = function (level, msg, meta, callback) {
|
||||
transport.log = function (level, msg, meta, callback) { // eslint-disable-line promise/prefer-await-to-callbacks
|
||||
let code = /\u001b\[(\d+(;\d+)*)?m/g;
|
||||
msg = ('' + msg).replace(code, '');
|
||||
_log(level, msg, meta, callback);
|
||||
|
||||
+11
@@ -132,6 +132,17 @@ async function main (args = null) {
|
||||
await server.close();
|
||||
throw err;
|
||||
}
|
||||
|
||||
process.once('SIGINT', async function () {
|
||||
logger.info(`Received SIGINT - shutting down`);
|
||||
await server.close();
|
||||
});
|
||||
|
||||
process.once('SIGTERM', async function () {
|
||||
logger.info(`Received SIGTERM - shutting down`);
|
||||
await server.close();
|
||||
});
|
||||
|
||||
logServerPort(args.address, args.port);
|
||||
|
||||
return server;
|
||||
|
||||
+1
-1
@@ -326,7 +326,7 @@ const args = [
|
||||
}],
|
||||
|
||||
[['--suppress-adb-kill-server'], {
|
||||
dest: 'suppressAdbKillServer',
|
||||
dest: 'suppressKillServer',
|
||||
defaultValue: false,
|
||||
action: 'storeTrue',
|
||||
required: false,
|
||||
|
||||
+39
-38
@@ -11,7 +11,7 @@
|
||||
"firefoxos",
|
||||
"testing"
|
||||
],
|
||||
"version": "1.6.0-beta3",
|
||||
"version": "1.6.4-beta",
|
||||
"author": "https://github.com/appium",
|
||||
"license": "Apache-2.0",
|
||||
"repository": {
|
||||
@@ -34,29 +34,29 @@
|
||||
"doc": "./docs"
|
||||
},
|
||||
"dependencies": {
|
||||
"appium-android-driver": "^1.10.27",
|
||||
"appium-base-driver": "^2.0.19",
|
||||
"appium-fake-driver": "^0.1.10",
|
||||
"appium-ios-driver": "^1.12.27",
|
||||
"appium-logger": "^2.1.0",
|
||||
"appium-selendroid-driver": "^1.3.4",
|
||||
"appium-support": "^2.3.3",
|
||||
"appium-uiautomator2-driver": "^0.x",
|
||||
"appium-xcuitest-driver": "^2.0.25",
|
||||
"appium-youiengine-driver": "^1.0.6",
|
||||
"appium-windows-driver": "^0.x",
|
||||
"argparse": "^1.0.7",
|
||||
"asyncbox": "^2.3.1",
|
||||
"appium-android-driver": "1.x",
|
||||
"appium-base-driver": "2.x",
|
||||
"appium-fake-driver": "0.x",
|
||||
"appium-ios-driver": "1.x",
|
||||
"appium-logger": "2.x",
|
||||
"appium-selendroid-driver": "1.x",
|
||||
"appium-support": "2.x",
|
||||
"appium-uiautomator2-driver": "0.x",
|
||||
"appium-xcuitest-driver": "2.x",
|
||||
"appium-youiengine-driver": "1.x",
|
||||
"appium-windows-driver": "0.x",
|
||||
"argparse": "1.x",
|
||||
"asyncbox": "2.x",
|
||||
"babel-runtime": "=5.8.24",
|
||||
"bluebird": "^2.10.2",
|
||||
"continuation-local-storage": "^3.1.7",
|
||||
"date-utils": "^1.2.21",
|
||||
"lodash": "^4.13.1",
|
||||
"npmlog": "^2.0.4",
|
||||
"request-promise": "^1.0.2",
|
||||
"source-map-support": "^0.4.0",
|
||||
"teen_process": "^1.7.1",
|
||||
"winston": "^2.2.0"
|
||||
"bluebird": "2.x",
|
||||
"continuation-local-storage": "3.x",
|
||||
"date-utils": "1.x",
|
||||
"lodash": "4.x",
|
||||
"npmlog": "2.x",
|
||||
"request-promise": "1.x",
|
||||
"source-map-support": "0.x",
|
||||
"teen_process": "1.x",
|
||||
"winston": "2.x"
|
||||
},
|
||||
"scripts": {
|
||||
"prepublish": "gulp prepublish",
|
||||
@@ -71,22 +71,23 @@
|
||||
"test"
|
||||
],
|
||||
"devDependencies": {
|
||||
"appium-gulp-plugins": "^1.4.5",
|
||||
"babel-eslint": "^6.1.0",
|
||||
"chai": "^3.5.0",
|
||||
"chai-as-promised": "^5.3.0",
|
||||
"eslint": "^2.13.1",
|
||||
"eslint-config-appium": "^0.0.8",
|
||||
"eslint-plugin-babel": "^3.3.0",
|
||||
"eslint-plugin-import": "^1.9.2",
|
||||
"eslint-plugin-mocha": "^3.0.0",
|
||||
"gulp": "^3.9.1",
|
||||
"mocha": "^2.5.3",
|
||||
"pre-commit": "^1.1.3",
|
||||
"sinon": "^1.17.4",
|
||||
"wd": "~0.4.0"
|
||||
"appium-gulp-plugins": "1.x",
|
||||
"babel-eslint": "6.x",
|
||||
"chai": "3.x",
|
||||
"chai-as-promised": "5.x",
|
||||
"eslint": "2.x",
|
||||
"eslint-config-appium": "0.x",
|
||||
"eslint-plugin-babel": "3.x",
|
||||
"eslint-plugin-import": "1.x",
|
||||
"eslint-plugin-mocha": "3.x",
|
||||
"eslint-plugin-promise": "3.x",
|
||||
"gulp": "3.x",
|
||||
"mocha": "2.x",
|
||||
"pre-commit": "1.x",
|
||||
"sinon": "1.x",
|
||||
"wd": "0.x"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"fsevents": "^1.0.12"
|
||||
"fsevents": "1.x"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
"trailing": true,
|
||||
"node": true,
|
||||
"eqeqeq": true,
|
||||
"trailing": true,
|
||||
"expr": true,
|
||||
"white": true,
|
||||
"indent": 2,
|
||||
|
||||
+38
-1
@@ -9,8 +9,9 @@ import chai from 'chai';
|
||||
import chaiAsPromised from 'chai-as-promised';
|
||||
import { XCUITestDriver } from 'appium-xcuitest-driver';
|
||||
import { IosDriver } from 'appium-ios-driver';
|
||||
import { sleep } from 'asyncbox';
|
||||
|
||||
|
||||
chai.should();
|
||||
chai.use(chaiAsPromised);
|
||||
|
||||
const BASE_CAPS = {platformName: 'Fake', deviceName: 'Fake', app: TEST_FAKE_APP};
|
||||
@@ -172,6 +173,42 @@ describe('AppiumDriver', () => {
|
||||
});
|
||||
describe('sessionExists', () => {
|
||||
});
|
||||
describe('attachUnexpectedShutdownHandler', () => {
|
||||
let appium
|
||||
, mockFakeDriver;
|
||||
beforeEach(() => {
|
||||
[appium, mockFakeDriver] = getDriverAndFakeDriver();
|
||||
});
|
||||
afterEach(() => {
|
||||
mockFakeDriver.restore();
|
||||
appium.args.defaultCapabilities = {};
|
||||
});
|
||||
|
||||
it('should remove session if inner driver unexpectedly exits with an error', async () => {
|
||||
let [sessionId,] = await appium.createSession(_.clone(BASE_CAPS)); // eslint-disable-line comma-spacing
|
||||
_.keys(appium.sessions).should.contain(sessionId);
|
||||
appium.sessions[sessionId].unexpectedShutdownDeferred.reject(new Error("Oops"));
|
||||
// let event loop spin so rejection is handled
|
||||
await sleep(1);
|
||||
_.keys(appium.sessions).should.not.contain(sessionId);
|
||||
});
|
||||
it('should remove session if inner driver unexpectedly exits with no error', async () => {
|
||||
let [sessionId,] = await appium.createSession(_.clone(BASE_CAPS)); // eslint-disable-line comma-spacing
|
||||
_.keys(appium.sessions).should.contain(sessionId);
|
||||
appium.sessions[sessionId].unexpectedShutdownDeferred.resolve();
|
||||
// let event loop spin so rejection is handled
|
||||
await sleep(1);
|
||||
_.keys(appium.sessions).should.not.contain(sessionId);
|
||||
});
|
||||
it('should not remove session if inner driver cancels unexpected exit', async () => {
|
||||
let [sessionId,] = await appium.createSession(_.clone(BASE_CAPS)); // eslint-disable-line comma-spacing
|
||||
_.keys(appium.sessions).should.contain(sessionId);
|
||||
appium.sessions[sessionId].onUnexpectedShutdown.cancel();
|
||||
// let event loop spin so rejection is handled
|
||||
await sleep(1);
|
||||
_.keys(appium.sessions).should.contain(sessionId);
|
||||
});
|
||||
});
|
||||
describe('getDriverForCaps', () => {
|
||||
it('should not blow up if user does not provide platformName', () => {
|
||||
let appium = new AppiumDriver({});
|
||||
|
||||
+2
-1
@@ -1,5 +1,6 @@
|
||||
import path from 'path';
|
||||
import wd from 'wd';
|
||||
import B from 'bluebird';
|
||||
|
||||
const TEST_HOST = 'localhost';
|
||||
const TEST_PORT = 4723;
|
||||
@@ -18,7 +19,7 @@ function initSession (caps) {
|
||||
after(async () => {
|
||||
await driver.quit();
|
||||
});
|
||||
return new Promise((_resolve) => {
|
||||
return new B((_resolve) => {
|
||||
resolve = _resolve;
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user