From fbc8feb529ab75a8b73b42ef80026a2998cf00b3 Mon Sep 17 00:00:00 2001 From: Eric Millin Date: Tue, 19 Aug 2014 12:26:33 -0400 Subject: [PATCH] Fix for #2969. Added ability to arbitrarily launch activities. --- .../writing-running-appium/appium-bindings.md | 36 +++++++++++++++++++ lib/devices/android/android-controller.js | 2 +- lib/devices/android/android.js | 32 +++++++++-------- lib/server/controller.js | 21 +++++++++-- lib/server/routing.js | 1 + package.json | 2 +- .../android/apidemos/basic-specs.js | 21 +++++++++++ 7 files changed, 97 insertions(+), 18 deletions(-) diff --git a/docs/en/writing-running-appium/appium-bindings.md b/docs/en/writing-running-appium/appium-bindings.md index bbb35ee66..47ba634d2 100644 --- a/docs/en/writing-running-appium/appium-bindings.md +++ b/docs/en/writing-running-appium/appium-bindings.md @@ -125,6 +125,42 @@ $this->hideKeyboard(array('strategy' => 'pressKey', 'key' => 'Done')); driver.HideKeyboard("Done"); ``` +### Start Activity + +Open an activity in the current app or start a new app and open an activity *Android only* + +```java +// java +driver.startActivity("appPackage","com.example.android.apis", null, null); +``` + +```javascript +// javascript +driver.startActivity({appPackage: 'com.example.android.apis', appActivity: '.Foo'}, cb); +``` + +```python +# python +driver.start_activity('com.example.android.apis', '.Foo') +``` + +```ruby +# ruby +start_activity app_package: 'io.appium.android.apis', app_activity: '.accessibility.AccessibilityNodeProviderActivity' +``` + +```csharp +// c# +driver.StartActivity("com.example.android.apis", ".Foo"); +``` + +```php +// php +$this->startActivity(array("appPackage" => "com.example.android.apis", + "appActivity" => ".Foo")); +``` + + ### Open Notifications Open the notification shade *Android only* diff --git a/lib/devices/android/android-controller.js b/lib/devices/android/android-controller.js index 943e75120..3f6abc994 100644 --- a/lib/devices/android/android-controller.js +++ b/lib/devices/android/android-controller.js @@ -707,7 +707,7 @@ androidController.resetAndStartApp = function (cb) { async.series([ this.resetApp.bind(this), this.waitForActivityToStop.bind(this), - this.startApp.bind(this) + this.startAppUnderTest.bind(this) ], cb); }; diff --git a/lib/devices/android/android.js b/lib/devices/android/android.js index f775c841c..43e272eeb 100644 --- a/lib/devices/android/android.js +++ b/lib/devices/android/android.js @@ -361,21 +361,25 @@ Android.prototype.pushAppium = function (cb) { }.bind(this)); }; -Android.prototype.startApp = function (cb) { - if (!this.args.androidCoverage) { - this.adb.startApp({ - pkg: this.args.appPackage, - activity: this.args.appActivity, - action: this.args.intentAction, - category: this.args.intentCategory, - flags: this.args.intentFlags, - waitPkg: this.args.appWaitPackage, - waitActivity: this.args.appWaitActivity, - optionalIntentArguments: this.args.optionalIntentArguments - }, cb); +Android.prototype.startAppUnderTest = function (cb) { + this.startApp(this.args, cb); +}; + +Android.prototype.startApp = function (args, cb) { + if (args.androidCoverage) { + this.adb.androidCoverage(args.androidCoverage, args.appWaitPackage, + args.appWaitActivity, cb); } else { - this.adb.androidCoverage(this.args.androidCoverage, this.args.appWaitPackage, - this.args.appWaitActivity, cb); + this.adb.startApp({ + pkg: args.appPackage, + activity: args.appActivity, + action: args.intentAction, + category: args.intentCategory, + flags: args.intentFlags, + waitPkg: args.appWaitPackage, + waitActivity: args.appWaitActivity, + optionalIntentArguments: args.optionalIntentArguments + }, cb); } }; diff --git a/lib/server/controller.js b/lib/server/controller.js index ce2197900..1681657d8 100644 --- a/lib/server/controller.js +++ b/lib/server/controller.js @@ -17,7 +17,8 @@ var status = require('./status.js') , helpers = require('../helpers.js') , logCustomDeprecationWarning = helpers.logCustomDeprecationWarning , _ = require('underscore') - , safely = require('./helpers').safely; + , safely = require('./helpers').safely + , NotImplementedError = require('./errors').NotImplementedError; exports.getGlobalBeforeFilter = function (appium) { return function (req, res, next) { @@ -124,6 +125,22 @@ exports.isAppInstalled = function (req, res) { } }; +exports.startActivity = function (req, res) { + var onErr = function (err) { + respondError(req, res, "Unable to launch the app: " + err); + }; + + // 8/21/14: currently not supported on all devices + if (!req.device.startApp) { + onErr(new NotImplementedError()); + } else { + req.device.startApp(req.body, function (err) { + if (err) return onErr(err); + respondSuccess(req, res, "Successfully launched the app."); + }); + } +}; + exports.launchApp = function (req, res) { var onErr = function (err) { respondError(req, res, "Unable to launch the app: " + err); @@ -140,7 +157,7 @@ exports.closeApp = function (req, res) { req.device.stop(function () { respondSuccess(req, res, "Successfully closed the [" + req.device.args.app + "] app."); }, function () { - respondError(req, res, "Something whent wront whilst closing the [" + req.device.args.app + "] app."); + respondError(req, res, "Something went wrong whilst closing the [" + req.device.args.app + "] app."); }); }; diff --git a/lib/server/routing.js b/lib/server/routing.js index 1f78c31e9..9fa3669b8 100644 --- a/lib/server/routing.js +++ b/lib/server/routing.js @@ -122,6 +122,7 @@ module.exports = function (appium) { rest.post('/wd/hub/session/:sessionId?/appium/device/toggle_wifi', controller.toggleWiFi); rest.post('/wd/hub/session/:sessionId?/appium/device/toggle_location_services', controller.toggleLocationServices); rest.post('/wd/hub/session/:sessionId?/appium/device/open_notifications', controller.openNotifications); + rest.post('/wd/hub/session/:sessionId?/appium/device/start_activity', controller.startActivity); rest.post('/wd/hub/session/:sessionId?/appium/app/launch', controller.launchApp); rest.post('/wd/hub/session/:sessionId?/appium/app/close', controller.closeApp); diff --git a/package.json b/package.json index 7792a95f0..d0eb8f443 100644 --- a/package.json +++ b/package.json @@ -119,7 +119,7 @@ "socks": "~0.0.1", "underscore-cli": "~0.2.17", "unorm": "~1.3.3", - "wd": "~0.3.4", + "wd": "~0.3.7", "wd-bridge": "~0.0.1", "yiewd": "~0.5.0" } diff --git a/test/functional/android/apidemos/basic-specs.js b/test/functional/android/apidemos/basic-specs.js index d6cb853b2..269acc731 100644 --- a/test/functional/android/apidemos/basic-specs.js +++ b/test/functional/android/apidemos/basic-specs.js @@ -128,7 +128,28 @@ describe("apidemo - basic @skip-ci", function () { }) .nodeify(done); }); + }); + describe('at any time', function () { + var driver; + setup(this, desired) + .then(function (d) { driver = d; }); + + it('should open an activity in this application', function (done) { + driver + .startActivity({appPackage: "io.appium.android.apis", appActivity: ".accessibility.AccessibilityNodeProviderActivity"}) + .getCurrentActivity() + .should.eventually.include("Node") + .nodeify(done); + }); + + it('should open an activity in another application', function (done) { + driver + .startActivity({appPackage: "com.android.contacts", appActivity: ".ContactsListActivity"}) + .getCurrentActivity() + .should.eventually.include("Contact") + .nodeify(done); + }); }); describe('with fastReset', function () {