Compare commits

...
59 Commits
Author SHA1 Message Date
Jonah Stiennon 41a29cef73 bump to 1.4.8 for real (not beta) 2015-07-15 15:29:02 -07:00
Jonah Stiennon 9786562587 bump to 1.4.8 2015-07-15 14:49:59 -07:00
Jonah Stiennon 943136d69c update appium-support to version 1.1.2 2015-07-14 11:58:47 -07:00
Jonathan Lipps a9442928f2 Merge pull request #5362 from Jonahss/status
have calls to /status endpoint hit the appium server and NOT be proxi…
2015-07-10 11:31:20 +08:00
Jonah Stiennon 29bd662572 have calls to /status endpoint hit the appium server and NOT be proxied to chromedriver when testing in chrome on android. fixes #5335 2015-07-09 18:00:59 -07:00
Moiz Virani 97ae607397 Merge pull request #5330 from moizjv/master
Bumping to version 1.4.7
2015-07-01 19:27:32 -07:00
moizjv 64453e98d3 Bumping to version 1.4.7 2015-07-01 19:20:35 -07:00
seb vincent cf29ba8ce4 Merge pull request #5329 from moizjv/master
Correct version of appium in shrinkwrap.json
2015-07-02 09:04:03 +08:00
moizjv f6f77293e8 Correct version of shrinkwrap 2015-07-01 18:00:35 -07:00
Jonathan Lipps ce1b549794 Merge pull request #5328 from moizjv/master
Adding socket.io-client back to devDep, regenerating shrinkwrap and bumping to beta3
2015-07-02 08:10:51 +08:00
moizjv 6c300e3ba2 Adding socket.io-client back to devDep, regenerating shrinkwrap and bumping to beta3 2015-07-01 17:08:08 -07:00
Moiz Virani ffdc47899c Merge pull request #5327 from moizjv/master
Adding socket.io-client as a dependency instead of dev dependency
2015-07-01 15:40:05 -07:00
moizjv 5b2f7fafbd Adding socket.io-client as a dependency instead of dev dependency 2015-07-01 15:37:59 -07:00
Jonathan Lipps b365ba7caa Merge pull request #5314 from moizjv/master
Bumping version to 1.4.7 beta, adding changes to changelog and npm-shrinkwrap
2015-06-30 12:04:25 -07:00
moizjv 61a99e56ab Bumping version to 1.4.7 beta, adding changes to changelog and npm-shrinkwrap 2015-06-30 12:01:04 -07:00
sebv 7c3f22c45f added --ignore-shrinkwrap option to reset.sh 2015-06-24 01:44:21 +08:00
Jonathan Lipps 1fd1c1bb44 Merge pull request #5279 from appium/sebv-nodeify-fix
Better promise handling
2015-06-22 08:38:32 -07:00
Jonathan Lipps a27ee52375 changelog and bump to 1.4.6 for publish..again 2015-06-19 10:27:18 -07:00
sebv 576a53d714 better promise handling 2015-06-19 20:13:11 +08:00
Jonathan Lipps 9d1af07681 add an escape hatch for force push prevention 2015-06-18 18:07:11 -07:00
Jonathan Lipps 5af75f101e bump to 1.4.5, since npm-shrinkwrap seems to work 2015-06-18 18:00:25 -07:00
Jonathan Lipps bd2a8bff36 changelog and bump to 1.4.5-beta to test if this new shrinkwrap works 2015-06-18 17:47:37 -07:00
Jonathan Lipps 8f951d1f93 change shrinkwrap to be generated by npm-shrinkwrap, seems to actually work 2015-06-18 17:45:33 -07:00
Jonathan Lipps fdcfc3088c stack-trace is not a dev dep, it's an actual dep 2015-06-18 17:29:15 -07:00
Jonathan Lipps a769778a94 changelog and bump to 1.4.4, also use npm shrinkwrap as we should have been doing all along 2015-06-18 16:58:32 -07:00
Jonathan Lipps 5ac788838d don't rely on async functions returning Promise objects; just use .then 2015-06-18 16:51:44 -07:00
Jonathan Lipps 32855b7cc0 update packweb with new deps 2015-06-18 15:57:47 -07:00
Jonathan Lipps c091694985 bring in new appium-chromedriver with chromedriver 2.16 2015-06-18 15:57:47 -07:00
sebv 50e11276af removes trailing spaces 2015-06-16 16:16:01 +08:00
Jonathan Lipps 22886a1937 Merge pull request #5247 from icecrystal23/patch-1
copyLocalZip doesn't check all possible errors
2015-06-11 14:36:22 -07:00
Tracy Keeling 68553ed916 copyLocalZip doesn't check all possible errors
One error wasn't reported, which made for a very confusing failure.  Adding this line helped us dig deeper into the actual issue we have.
2015-06-11 12:25:23 -07:00
Jonathan Lipps 6d23089d12 Merge pull request #5242 from WKPlus/master
add help information for command-timeout option
2015-06-11 12:02:53 -07:00
WKPlus 8930b9e4ab add help information for command-timeout option
add help information for command-timeout option: the option is in seconds and should be less than 2147483 since setTimeout using a 32 bit int to store the delay
2015-06-11 16:18:12 +08:00
Jonathan Lipps 5c1200e23c Merge pull request #5238 from imurchie/isaac-context-errors
Add ability to configure remote debugger connection retries
2015-06-10 12:31:43 -07:00
Isaac Murchie 6491fda813 Add ability to configure remote debugger connection retries 2015-06-10 12:10:12 -07:00
Jonathan Lipps 288446add2 also update appium-instruments submodule since we do that still 2015-06-09 10:26:23 -07:00
Jonathan Lipps 5587d08453 update appium-instruments with subdep fix, bump to 1.4.3 and changelog 2015-06-09 10:23:36 -07:00
Jonathan Lipps ab96bccf28 bump version to 1.4.2 2015-06-08 17:22:07 -07:00
Jonathan Lipps 51fdfeb4e0 changelog for 1.4.1 and 1.4.2 2015-06-08 14:27:07 -07:00
Jonathan Lipps cf19544579 upgrade es6 deps to fix babel/regenerator issue 2015-06-08 14:18:14 -07:00
Jonathan Lipps 42aca68fd1 fix typo 2015-06-03 11:37:57 +01:00
Jonathan Lipps 4057a81731 add roadmap doc and link from readme 2015-06-03 11:36:11 +01:00
Jonathan Lipps 2113a4cb45 Merge pull request #5196 from imurchie/isaac-safari
Keep track of the correct app id for safari webview
2015-06-02 20:09:58 +01:00
Isaac Murchie 8e3aaf8d44 Keep track of the correct app id for safari webview 2015-06-02 09:45:19 -07:00
Jonathan Lipps abe9ec34d1 Merge pull request #5174 from whoward/ios-simulator-app-installation-and-removal
delegate ios simulator app installation/removal/launching to simctl
2015-06-02 11:04:45 +01:00
Jonathan Lipps 7d1082aec1 Merge pull request #5189 from imurchie/isaac-contentdescription
Allow access to element content description attribute directly
2015-06-02 08:00:15 +01:00
Isaac Murchie 3c6b0889c9 Allow access to element content description attribute directly 2015-06-01 11:24:47 -07:00
Jonathan Lipps e6927c60e2 Merge pull request #5183 from Jonahss/iRealD
fixing iOS real device tests
2015-05-29 11:46:11 -07:00
sebv 023049fc1e moved jenkins-tools to jenkins-gulper 2015-05-29 21:04:45 +08:00
sebv 68255c4a44 fixing submodules 2015-05-29 15:15:27 +08:00
sebv 1c39f50240 ci fixes, moved appium-ci-gulper to appium-ci/jenkins-tools 2015-05-29 14:38:13 +08:00
Jonah Stiennon 22dc8bc5e6 fix a bug in iOS LookForAlert 2015-05-28 19:22:55 -07:00
Jonah Stiennon 13a64d9709 skip performance log test 2015-05-28 19:22:55 -07:00
William Howard 586ee9baf6 delegate ios simulator app installation/removal/launching to simctl 2015-05-27 11:24:31 -04:00
Jonathan Lipps d5abb9f48e update node-bplist-parser to 0.1.0 with internationalization fixes 2015-05-26 10:57:10 -07:00
Jonathan Lipps d143fd3432 Merge pull request #5153 from whoward/chromedriver-dont-proxy-appium
don't proxy chromedriver requests for /wd/hub/:session_id/appium/*
2015-05-26 10:33:25 -07:00
Jonathan Lipps 4ce4d44e87 Merge pull request #5154 from imurchie/isaac-ios-appfullpath
Allow for a - in iOS app name
2015-05-25 05:42:26 -07:00
Isaac Murchie 0a831eab47 Allow for a - in iOS app name 2015-05-22 07:45:32 -07:00
William Howard 6f8795090d don't proxy chromedriver requests for /wd/hub/:session_id/appium/* 2015-05-22 09:52:06 -04:00
33 changed files with 3648 additions and 99 deletions
+3 -3
View File
@@ -49,7 +49,7 @@
[submodule "submodules/deviceconsole"]
path = submodules/deviceconsole
url = https://github.com/rpetrich/deviceconsole.git
[submodule "submodules/appium-ci-gulper"]
path = submodules/appium-ci-gulper
url = https://github.com/appium/appium-ci-gulper.git
[submodule "submodules/appium-ci"]
path = submodules/appium-ci
url = https://github.com/appium/appium-ci.git
branch = master
+69
View File
@@ -6,6 +6,75 @@ CHANGES IN VERSION 1.5 (from 1.4.?)
- add Tapster support for some more touch methods
CHANGES IN VERSION 1.4.8 (from 1.4.7)
===================================
#### General
- fix for Windows users! Now the system architecture is properly detected, npm installs should work again
#### Chromedriver / Android hybrid
- fix for an issue in responding to `/status` api endpoint, this is used heavily by Selenium grid
CHANGES IN VERSION 1.4.7 (from 1.4.6)
===================================
#### Chromedriver / Android hybrid
- fix for problem in downstream jsonwp-proxy; now sessionId returned is replaced
with sessionId present in url(original sessionId). Fixed this in appium-jsonwp-proxy 1.2.3
CHANGES IN VERSION 1.4.6 (from 1.4.5)
===================================
#### General
- this is a republish because of a misconfiguration before 1.4.5 got published
resulting in a server startup failure
CHANGES IN VERSION 1.4.5 (from 1.4.4)
===================================
#### General
- fix problem with npm shrinkwrap that caused Appium not to start
CHANGES IN VERSION 1.4.4 (from 1.4.3)
===================================
#### Chromedriver / Android hybrid
- fix a problem in downstream appium-chromedriver; no longer rely on async
methods returning objects of the Promise type. This was causing undefined
errors when running Chromedriver/hybrid tests.
CHANGES IN VERSION 1.4.3 (from 1.4.2)
===================================
#### iOS
- update the appium-instruments dependency with working subdeps
CHANGES IN VERSION 1.4.2 (from 1.4.1)
===================================
#### General
- update ES6-based dependencies which got bit by a breaking Regenerator
change
#### iOS
- keep track of the correct app ID for Safari webviews (fixes problems in
finding the webview for iOS)
#### Android
- fix sendKeys and clear for Samsung devices
CHANGES IN VERSION 1.4.1 (from 1.4)
===================================
#### Chromedriver
- have the appium-chromedriver manage the chromedriver binary download/install
CHANGES IN VERSION 1.4 (from 1.3.7)
======================================
+4 -2
View File
@@ -12,8 +12,6 @@
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, FirefoxOS).
**Note:** we have just recently released Appium 1.0. If you already have a bunch of Appium tests, you might want to check out the [Migrating to 1.0](/docs/en/advanced-concepts/migrating-to-1-0.md) doc!
### Supported Platforms
* iOS
@@ -133,6 +131,10 @@ Gecko-based platforms.
Please take a look at our [contribution documentation](CONTRIBUTING.md)
for instructions on how to build, test and run Appium from source.
### Roadmap
Interested in where Appium is heading in the future? Check out the [Roadmap](ROADMAP.md)
### Project Credits & Inspiration
[Credits](/docs/en/contributing-to-appium/credits.md)
+46
View File
@@ -0,0 +1,46 @@
Appium Roadmap
---------------
This document is designed to be a living record of the current and projected
priorities for the Appium project. It is, of course, always subject to change
and exists solely to give the community an idea of where we're going. The
roadmap is set by the Appium core team. If you have feature suggestions for
Appium, please submit a [GitHub issue](https://github.com/appium/appium/issues)
and, if of sufficient size and approved by the team, it will be added here. If
you have concerns about the roadmap, you can e-mail the Appium devs at
`appium-developers@googlegroups.com`. Note that bugfixes and miscellaneous
features are not considered "roadmap projects", and will be addressed in the
due course of normal Appium development. This page exists to outline
large-scale future plans for Appium.
## Current Roadmap Projects
| 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.|8/2015|1.5|
## Upcoming Projects (in rough order of priority)
| Project | Description |
|---------|-------------|
|iOS 8.4 support|Appium should support iOS 8.4 / Xcode 6.2|
|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.|
|DroidDriver backend integration|Appium's current UiAutomator-based approach to Android automation has a number of issues. We have been investigating [DroidDriver](https://github.com/appium/droiddriver) as a potential replacement. This project (dependend on the rearchitecture) would add DroidDriver as a new `automationBackend`, ideally aiming for feature parity with the current Android support. If successful, the UiAutomator backend would be deprecated and eventually removed.|
|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.|
## Projects Under Consideration (unprioritized)
| Project | Description |
|---------|-------------|
|Non-UIAutomation iOS backend|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 a different approach (a la [Calabash](https://github.com/calabash/calabash-ios)), even though it's in tension with Appium's philosophy of not modifying your app, in order to see if the overall experience is more stable. This new backend would exist alongside the UIAutomation backend.|
|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.|
|FirefoxOS Support|Our initial support for FirefoxOS has not been updated. It should be re-added as a FirefoxOSDriver in the new architecture|
## Completed Roadmap Projects
| Project | Description | Completed | Appium Release | Notes |
|---------|-------------|-----------|----------------|-------|
|Appium CI|Appium has unique needs for Continuous Integration because of the highly specialized environments required (iOS simulators, Xcode, Android emulators, the Android SDK, etc...). We therefore need to create a custom CI solution (perhaps sitting underneath Cloudbees or some other OSS-friendly CI server) that can be used for all Appium projects which need integration tests.|5/2015|_N/A_|Usage instructions at [appium/appium-ci](https://github.com/appium/appium-ci)|
+5 -5
View File
@@ -2,15 +2,15 @@
{ set -e; } 2>/dev/null
{ set -x; } 2>/dev/null
# Loading appium-ci-gulper submodule
# Loading appium-ci submodule
export APPIUM_ROOT="$(pwd)"
git submodule update --remote --init submodules/appium-ci-gulper
pushd submodules/appium-ci-gulper
git submodule update --remote --init submodules/appium-ci
pushd submodules/appium-ci
git pull origin master
{ set +x; } 2>/dev/null
popd
# Running appium-ci-gulper submodule
# This sets up node etc...
pushd submodules/appium-ci/jenkins-gulper
source ./setup
{ set -x; } 2>/dev/null
+1
View File
@@ -86,3 +86,4 @@
|`sendKeyStrategy`| strategy to use to type test into a test field. Simulator default: `oneByOne`. Real device default: `grouped` |`oneByOne`, `grouped` or `setValue`|
|`screenshotWaitTimeout`| Max timeout in sec to wait for a screenshot to be generated. default: 10 |e.g., `5`|
|`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`|
+12 -19
View File
@@ -6,7 +6,8 @@ var logger = require('../../server/logger.js').get('appium')
, UnknownError = errors.UnknownError
, async = require('async')
, Chromedriver = require('appium-chromedriver')
, status = require("../../server/status.js");
, status = require("../../server/status.js")
, Q = require('q');
var androidHybrid = {};
@@ -168,15 +169,12 @@ androidHybrid.setupNewChromedriver = function (context, cb) {
this.onChromedriverStop(context);
}
}.bind(this));
this.chromedriver.start(caps).nodeify(function (err) {
if (err) return cb(err);
new Q(this.chromedriver.start(caps)).then(function () {
// save the chromedriver object under the context
this.sessionChromedrivers[context] = this.chromedriver;
cb();
}.bind(this));
}.bind(this)).nodeify(cb);
};
androidHybrid.setupExistingChromedriver = function (context, cb) {
logger.debug("Found existing Chromedriver for context '" + context + "'." +
" Using it.");
@@ -187,18 +185,15 @@ androidHybrid.setupExistingChromedriver = function (context, cb) {
// check the status by sending a simple window-based command to ChromeDriver
// if there is an error, we want to recreate the ChromeDriver session
this.chromedriver.hasWorkingWebview().nodeify(function (err, works) {
if (err) return cb(err);
if (works) return cb();
new Q(this.chromedriver.hasWorkingWebview()).then(function (works) {
if (works) return;
logger.debug("ChromeDriver is not associated with a window. " +
"Re-initializing the session.");
this.chromedriverRestartingContext = context;
this.chromedriver.restart().nodeify(function (err) {
if (err) return cb(err);
return new Q(this.chromedriver.restart()).then(function () {
this.chromedriverRestartingContext = null;
cb();
}.bind(this));
}.bind(this));
}.bind(this)).nodeify(cb);
};
androidHybrid.onChromedriverStop = function (context) {
@@ -237,12 +232,10 @@ androidHybrid.stopChromedriverProxies = function (ocb) {
logger.debug("Stopping chromedriver for context " + context);
// stop listening for the stopped state event
this.sessionChromedrivers[context].removeAllListeners(Chromedriver.EVENT_CHANGED);
this.sessionChromedrivers[context].stop().nodeify(function (err) {
if (err) logger.warn("Error stopping Chromedriver: " + err.message);
// chromedriver isn't valid anymore, so remove it from context list
delete this.sessionChromedrivers[context];
cb();
}.bind(this));
new Q(this.sessionChromedrivers[context].stop())
.catch(function (err) { logger.warn("Error stopping Chromedriver: " + err.message); })
.finally(function () { delete this.sessionChromedrivers[context]; }.bind(this))
.nodeify(cb);
}.bind(this), function (err) {
// if one of these fails, go back to last proxy state and error out
this.restoreProxyState();
@@ -41,7 +41,7 @@ public class AndroidElement {
public boolean click() throws UiObjectNotFoundException {
return el.click();
}
public boolean exists() {
return el.exists();
}
@@ -65,13 +65,13 @@ public class AndroidElement {
return false;
}
}
public Point getAbsolutePosition(final Point point)
throws UiObjectNotFoundException, InvalidCoordinatesException {
final Rect rect = this.getBounds();
Logger.debug("Element bounds: " + rect.toShortString());
return PositionHelper.getAbsolutePosition(point, rect, new Point(rect.left, rect.top), false);
}
@@ -171,6 +171,8 @@ public class AndroidElement {
if (res.equals("")) {
res = getText();
}
} else if (attr.equals("contentDescription")) {
res = getContentDesc();
} else if (attr.equals("text")) {
res = getText();
} else if (attr.equals("className")) {
@@ -33,8 +33,9 @@ public class GetAttribute extends CommandHandler {
try {
final AndroidElement el = command.getElement();
final String attr = params.get("attribute").toString();
if (attr.equals("name") || attr.equals("text")
|| attr.equals("className") || attr.equals("resourceId")) {
if (attr.equals("name") || attr.equals("contentDescription")
|| attr.equals("text") || attr.equals("className")
|| attr.equals("resourceId")) {
return getSuccessResult(el.getStringAttribute(attr));
} else {
return getSuccessResult(String.valueOf(el.getBoolAttribute(attr)));
+14 -10
View File
@@ -8,7 +8,8 @@ var Android = require('./android.js')
, deviceCommon = require('../common.js')
, jwpSuccess = deviceCommon.jwpSuccess
, async = require('async')
, UiAutomator = require('./uiautomator.js');
, UiAutomator = require('./uiautomator.js')
, Q = require('q');
var NATIVE_WIN = "NATIVE_APP";
var WEBVIEW_WIN = "WEBVIEW";
@@ -33,12 +34,15 @@ ChromeAndroid.prototype.setChromedriverMode = function () {
// when proxying to chromedriver, we need to make sure the context endpoints
// are trapped by appium for its own purposes
this.avoidProxy = [
['GET', new RegExp('^/wd/hub/status.*')],
['POST', new RegExp('^/wd/hub/session/[^/]+/context')],
['GET', new RegExp('^/wd/hub/session/[^/]+/context')],
['POST', new RegExp('^/wd/hub/session/[^/]+/touch/perform')],
['POST', new RegExp('^/wd/hub/session/[^/]+/touch/multi/perform')],
['POST', new RegExp('^/wd/hub/session/[^/]+/orientation')],
['GET', new RegExp('^/wd/hub/session/[^/]+/orientation')]
['GET', new RegExp('^/wd/hub/session/[^/]+/orientation')],
['POST', new RegExp('^/wd/hub/session/[^/]+/appium')],
['GET', new RegExp('^/wd/hub/session/[^/]+/appium')]
];
};
@@ -153,20 +157,20 @@ ChromeAndroid.prototype.createSession = function (cb) {
this.onChromedriverStop(this.onDieCb);
}
}.bind(this));
this.chromedriver.start(caps).nodeify(function (err) {
if (err) return cb(err);
cb(null, this.chromedriver.sessionId());
}.bind(this));
new Q(this.chromedriver.start(caps)).then(function () {
return this.chromedriver.sessionId();
}.bind(this)).nodeify(cb);
};
ChromeAndroid.prototype.stop = function (cb) {
// stop listening for the stopped state event
this.chromedriver.removeAllListeners(Chromedriver.EVENT_CHANGED);
// now we can handle the stop on our own
this.chromedriver.stop().nodeify(function (err) {
if (err) logger.warn("Error stopping Chromedriver: " + err.message);
this.onChromedriverStop(cb);
}.bind(this));
new Q(this.chromedriver.stop())
.catch(function (err) { logger.warn("Error stopping Chromedriver: " + err.message); })
.finally(function () {
this.onChromedriverStop(cb); // TODO: do not rely on class method for callback
}.bind(this)).done();
};
ChromeAndroid.prototype.onChromedriverStop = function (cb) {
+2 -3
View File
@@ -519,13 +519,12 @@ iOSController._getFullPath = function (remotePath, cb) {
var appName = null;
if (this.args.app) {
var appNameRegex = new RegExp("\\" + path.sep + "(\\w+\\.app)");
var appNameRegex = new RegExp("\\" + path.sep + "([\\w-]+\\.app)");
var appNameMatches = appNameRegex.exec(this.args.app);
if (appNameMatches) {
appName = appNameMatches[1];
}
}
// de-absolutize the path
if (isWindows()) {
if (remotePath.indexof("://") === 1) {
@@ -717,7 +716,7 @@ iOSController.lookForAlert = function (cb, counter, looks, timeout) {
// so we can proxy the alert detection functionality
this.alertCounter++;
this.proxy("au.alertIsPresent()", function (err, res) {
if (res !== null) {
if (res) {
if (res.value === true) {
logger.debug("Found an alert, returning control to client");
this.returnedFromExecuteAtom[counter] = true;
+8 -4
View File
@@ -77,9 +77,11 @@ iOSHybrid.listWebFrames = function (cb, exitCb) {
if (this.remoteAppKey === null) {
return cb(new Error("remote debug app key must be set"));
}
this.remote.selectApp(this.remoteAppKey, function (res) {
this.remote.selectApp(this.remoteAppKey, function (err, perhapsModifiedAppKey, res) {
if (err) return onDone(err);
this.remoteAppKey = perhapsModifiedAppKey;
onDone(null, res);
});
}.bind(this), this.args.webviewConnectRetries);
}
} else {
if (this.args.udid !== null) {
@@ -107,9 +109,11 @@ iOSHybrid.listWebFrames = function (cb, exitCb) {
}
logger.debug("Using remote debugger app key: " + appKey);
this.remoteAppKey = appKey;
this.remote.selectApp(appKey, function (res) {
this.remote.selectApp(appKey, function (err, perhapsModifiedAppKey, res) {
if (err) return onDone(err);
this.remoteAppKey = perhapsModifiedAppKey;
onDone(null, res);
});
}.bind(this), this.args.webviewConnectRetries);
}.bind(this), this.onPageChange.bind(this));
var loopCloseRuns = 0;
var loopClose = function () {
+10 -2
View File
@@ -1494,7 +1494,7 @@ IOS.prototype.removeApp = function (bundleId, cb) {
if (this.args.udid) {
this.realDevice.remove(bundleId, cb);
} else {
cb(new Error("You can not call removeApp for the iOS simulator!"));
this.sim.remove(bundleId, cb);
}
};
@@ -1502,7 +1502,15 @@ IOS.prototype.installApp = function (unzippedAppPath, cb) {
if (this.args.udid) {
this.realDevice.install(unzippedAppPath, cb);
} else {
cb(new Error("You can not call installApp for the iOS simulator!"));
this.sim.install(unzippedAppPath, cb);
}
};
IOS.prototype.startApp = function (args, cb) {
if (this.args.udid) {
cb(new Error("You can not call startApp for a real device!"));
} else {
this.sim.launch(args.appPackage, cb);
}
};
+11 -9
View File
@@ -18,6 +18,7 @@ var net = require('net')
// CONFIG
// ====================================
var CONNECTION_RETRIES = 8;
var RemoteDebugger = function (onDisconnect) {
this.init(2, onDisconnect);
@@ -131,12 +132,13 @@ RemoteDebugger.prototype.setConnectionKey = function (cb) {
});
};
RemoteDebugger.prototype.selectApp = function (appIdKey, cb, tries) {
RemoteDebugger.prototype.selectApp = function (appIdKey, cb, maxTries, tries) {
if (_.isUndefined(maxTries)) maxTries = CONNECTION_RETRIES;
if (_.isUndefined(tries)) tries = 1;
try { assert.ok(this.connId); } catch (err) { return cb(err); }
this.appIdKey = appIdKey;
var connectToApp = messages.connectToApp(this.connId, this.appIdKey);
this.logger.debug("Selecting app " + this.appIdKey + " (try #" + tries + ")");
this.logger.debug("Selecting app " + this.appIdKey + " (try #" + tries + " of " + maxTries + ")");
var responded = false;
var onConnect = function (appIdKey, pageDict) {
@@ -150,25 +152,26 @@ RemoteDebugger.prototype.selectApp = function (appIdKey, cb, tries) {
return onRequiresRetry(this.appIdKey, msg);
}
if (responded) return;
this.logger.debug('Connected to app ' + appIdKey + ' [' + JSON.stringify(this.pageArrayFromDict(pageDict)) + ']');
responded = true;
cb(this.pageArrayFromDict(pageDict));
cb(null, appIdKey, this.pageArrayFromDict(pageDict));
this.specialCbs['_rpc_forwardGetListing:'] = this.onPageChange.bind(this);
}.bind(this);
var onRequiresRetry = function (correctAppIdKey, msg) {
if (responded) return;
responded = true;
if (tries < 4) {
if (tries < maxTries) {
if (!msg) {
msg = "We were notified we connected to possibly the wrong " +
"app. Using the id key suggested and trying again";
}
this.logger.info(msg);
this.selectApp(correctAppIdKey, cb, tries + 1);
this.selectApp(correctAppIdKey, cb, maxTries, tries + 1);
} else {
msg = "Could not connect to a valid app after " + tries + " tries.";
this.logger.error(msg);
cb(new Error(msg));
this.logger.debug(msg);
this.logger.debug("Could not connect to a valid app after " + tries + " tries.");
cb();
}
}.bind(this);
@@ -592,7 +595,6 @@ RemoteDebugger.prototype.send = function (data, cb, cb2) {
if (data.__selector === '_rpc_reportIdentifier:') {
this.specialCbs.connect = cb2;
} else if (data.__selector === '_rpc_forwardGetListing:') {
this.logger.debug(cb2);
this.specialCbs.connectedToBadApp = cb2;
}
} else if (data.__argument && data.__argument.WIRSocketDataKey) {
+41
View File
@@ -648,4 +648,45 @@ Simulator.prototype.deleteOtherSims = function (cb) {
}.bind(this));
};
Simulator.prototype.getBootedDevice = function (cb) {
simctl.getDevices(function (err, devices) {
if (err) return cb(err);
var booted = null;
_.detect(devices, function (sdkDevices) {
booted = _.findWhere(sdkDevices, {state: "Booted"});
return !!booted;
});
if (booted) {
cb(null, booted.udid);
} else {
cb("Simctl couldn't find any booted device");
}
});
};
Simulator.prototype.remove = function (bundleId, cb) {
this.getBootedDevice(function (err, udid) {
if (err) return cb(err);
simctl.removeApp(udid, bundleId, cb);
});
};
Simulator.prototype.install = function (appPath, cb) {
this.getBootedDevice(function (err, udid) {
if (err) return cb(err);
simctl.installApp(udid, appPath, cb);
});
};
Simulator.prototype.launch = function (bundleId, cb) {
this.getBootedDevice(function (err, udid) {
if (err) return cb(err);
simctl.launch(udid, bundleId, cb);
});
};
module.exports = Simulator;
+1
View File
@@ -40,6 +40,7 @@ exports.copyLocalZip = function (localZipPath, cb) {
fs.stat(localZipPath, function (err) {
if (err) return cb(err);
tempDir.open({prefix: 'appium-app', suffix: '.zip'}).nodeify(function (err, info) {
if (err) return cb(err);
var infile = fs.createReadStream(localZipPath);
var outfile = fs.createWriteStream(info.path);
infile.pipe(outfile).on('close', function () {
+1
View File
@@ -92,6 +92,7 @@ var iosCaps = [
, 'loggingPrefs'
, 'sendKeyStrategy'
, 'waitForAppScript'
, 'webviewConnectRetries'
];
var Capabilities = function (capabilities) {
+2 -1
View File
@@ -531,7 +531,8 @@ var args = [
, type: 'int'
, required: false
, help: 'The default command timeout for the server to use for all ' +
'sessions. Will still be overridden by newCommandTimeout cap'
'sessions (in seconds and should be less than 2147483). ' +
'Will still be overridden by newCommandTimeout cap'
}],
[['--keep-keychains'], {
+3348
View File
File diff suppressed because it is too large Load Diff
+8 -8
View File
@@ -11,7 +11,7 @@
"firefoxos",
"testing"
],
"version": "1.4.0",
"version": "1.4.8",
"author": "https://github.com/appium",
"licenses": [
{
@@ -43,17 +43,17 @@
"adm-zip": "~0.4.7",
"appium-adb": "=1.7.5",
"appium-atoms": "=0.0.5",
"appium-chromedriver": "^2.0.0",
"appium-instruments": "=2.0.2",
"appium-support": "=1.0.5",
"appium-chromedriver": "^2.1.3",
"appium-instruments": "^2.0.4",
"appium-support": "=1.1.2",
"appium-uiauto": "=1.10.8",
"appium-xcode": "=2.0.4",
"appium-xcode": "^2.0.5",
"argparse": "~1.0.1",
"async": "~0.9.0",
"binary-cookies": "~0.1.1",
"body-parser": "~1.12.0",
"bplist-creator": "~0.0.5",
"bplist-parser": "~0.0.6",
"bplist-parser": "^0.1.0",
"bufferpack": "0.0.6",
"bytes": "~1.0.0",
"camel-back-promise": "^1.0.0",
@@ -75,7 +75,7 @@
"namp": "0.2.25",
"ncp": "~2.0.0",
"node-idevice": "~0.1.5",
"node-simctl": "=2.0.0",
"node-simctl": "^2.0.1",
"node-uuid": "~1.4.2",
"npmlog": "~1.1.0",
"path": "~0.11.14",
@@ -88,6 +88,7 @@
"sandboxed-module": "~2.0.0",
"serve-favicon": "~2.2.0",
"socket.io": "~1.3.4",
"stack-trace": "0.0.9",
"swig": "~1.4.2",
"temp": "~0.8.1",
"through": "~2.3.6",
@@ -141,7 +142,6 @@
"socks": "~0.0.1",
"spawn-mocha-parallel": "~1.3.1",
"split": "^0.3.3",
"stack-trace": "0.0.9",
"uncolor": "~0.3.0",
"underscore-cli": "~0.2.18",
"unorm": "~1.3.3",
+2
View File
@@ -11,9 +11,11 @@
"appium-atoms",
"appium-base-driver",
"appium-chromedriver",
"appium-fake-driver",
"appium-jsonwp-proxy",
"appium-logger",
"appium-instruments",
"appium-selendroid-driver",
"appium-support",
"appium-express",
"appium-uiauto",
+4 -2
View File
@@ -29,6 +29,7 @@ verbose=false
chromedriver_version=false
chromedriver_install_all=false
npmlink=true
shrinkwrap_opt=""
if test -d .git ; then
is_git_checkout=true
else
@@ -56,6 +57,7 @@ do
"--chromedriver-install-all") chromedriver_install_all=true;;
"--udid") udid=$2;;
"--no-npmlink") npmlink=false;;
"--no-shrinkwrap") shrinkwrap_opt="--no-shrinkwrap";;
esac
if [[ -n "$2" ]] && [[ "$2" != --* ]]; then
@@ -121,10 +123,10 @@ reset_npm() {
fi
if $prod_deps ; then
echo "* Installing new or updated NPM modules"
run_cmd npm install --production .
run_cmd npm install --production $shrinkwrap_opt .
else
echo "* Installing new or updated NPM modules (including devDeps)"
run_cmd npm install .
run_cmd npm install $shrinkwrap_opt .
fi
}
@@ -34,6 +34,11 @@ describe("apidemos - attributes", function () {
.back()
.nodeify(done);
});
it('should be able to find content description attribute', function (done) {
driver.elementByName('Animation').getAttribute('contentDescription')
.should.become("Animation")
.nodeify(done);
});
it('should be able to find displayed attribute', function (done) {
driver
.elementByName('Animation').getAttribute('displayed')
+2 -2
View File
@@ -4,7 +4,7 @@ var setup = require("../common/setup-base")
, _ = require("underscore")
, getAppPath = require('../../helpers/app').getAppPath;
describe('crash recovery', function () {
describe('crash recovery @skip-real-device', function () {
var driver;
var desired = {
app: getAppPath('TestApp')
@@ -25,7 +25,7 @@ describe('crash recovery', function () {
});
});
describe('crash commands', function () {
describe('crash commands @skip-real-device', function () {
var driver;
var desired = {
@@ -36,7 +36,8 @@ describe('safari - webview - special capabilities @skip-ios6', function () {
});
});
describe('performance logs', function () {
// skipped on real devices, see https://github.com/appium/appium/issues/5166
describe('performance logs @skip-real-device', function () {
var driver;
var specialCaps = _.clone(desired);
specialCaps.loggingPrefs = {performance: 'ALL'};
@@ -50,9 +50,12 @@ describe('safari - windows and frames (' + env.DEVICE + ') @skip-ios6"', functio
.elementById('only_on_page_2')
.nodeify(done);
});
it("should be able to open js popup windows with safariAllowPopups set to true", function (done) {
// broken on real devices, see https://github.com/appium/appium/issues/5167
it("should be able to open js popup windows with safariAllowPopups set to true @skip-real-device", function (done) {
driver
.execute("window.open('/test/guinea-pig2.html', null);")
.elementByLinkText('i am a new window link')
.click()
.then(function () { return spinTitle("I am another page title", driver, 30); })
.nodeify(done);
});
+24 -15
View File
@@ -49,7 +49,7 @@ describe('testapp - device', function () {
});
});
describe('invalid deviceName @skip-ios6', function () {
describe('invalid deviceName @skip-ios6 @skip-real-device', function () {
var newDesired = _.extend(_.clone(desired), {deviceName: "iFailure 3.5-inch"});
var session = initSession(newDesired, {'no-retry': true});
@@ -60,23 +60,32 @@ describe('testapp - device', function () {
});
});
_.each(['iPhone', 'iPad'], function (device) {
describe('generic ' + device + ' deviceName @skip-ios6', function () {
var newDesired = _.extend(_.clone(desired), {
deviceName: device + " Simulator"
});
var session = initSession(newDesired, {'no-retry': true});
describe('generic deviceName @skip-ios6', function () {
var session;
after(function (done) {
session.tearDown(this.currentTest.state === 'passed').nodeify(done);
});
it('should work with a generic ' + device + ' deviceName', function (done) {
session.setUp()
.nodeify(done);
});
afterEach(function (done) {
session.tearDown(this.currentTest.state === 'passed').nodeify(done);
});
it('should work with a generic iPhone deviceName', function (done) {
var newDesired = _.extend(_.clone(desired), {
deviceName: "iPhone Simulator"
});
session = initSession(newDesired, {'no-retry': true});
session.setUp()
.nodeify(done);
});
it('should work with a generic iPad deviceName', function (done) {
var newDesired = _.extend(_.clone(desired), {
deviceName: "iPad Simulator"
});
session = initSession(newDesired, {'no-retry': true});
session.setUp()
.nodeify(done);
});
});
describe("real device", function () {
@@ -29,7 +29,7 @@ describe('localization - locale', function () {
});
});
describe('changing locale', function () {
describe('changing locale @skip-real-device', function () {
var driver;
setup(this, _.defaults({locale: 'fr'}, desired)).then(function (d) { driver = d; });
@@ -40,7 +40,7 @@ describe('localization - locale', function () {
});
});
describe('changing back', function () {
describe('changing back @skip-real-device', function () {
var driver;
setup(this, _.defaults({locale: 'en_US'}, desired)).then(function (d) { driver = d; });
@@ -75,7 +75,7 @@ describe('testapp - location - 3 @skip-ci', function () {
});
// TODO: location tests are not working well on sauce
describe('testapp - location - 4 @skip-ci', function () {
describe('testapp - location - 4 @skip-ci @skip-real-device', function () {
var driver;
var newDesired = _.clone(desired);
_.extend(newDesired, {
+4
View File
@@ -1,6 +1,10 @@
#!/bin/bash
# Prevents force-pushing to master
if $ALLOW_FORCE_PUSH; then
exit 0
fi
BRANCH=`git rev-parse --abbrev-ref HEAD`
PUSH_COMMAND=`ps -ocommand= -p $PPID`
PROTECTED_BRANCHES="^(master)"