diff --git a/lib/server/controller.js b/lib/server/controller.js index 0fdf877f8..de70af1c8 100644 --- a/lib/server/controller.js +++ b/lib/server/controller.js @@ -408,7 +408,7 @@ exports.mobileDrag = function (req, res) { exports.find = function (req, res) { var strategy = "dynamic" - , selector = req.body + , selector = req.body.selector , all = selector && selector[0] && typeof selector[0] === "string" && selector[0].toLowerCase() === "all"; if (all) { diff --git a/lib/server/routing.js b/lib/server/routing.js index 39b73c5ae..817a94857 100644 --- a/lib/server/routing.js +++ b/lib/server/routing.js @@ -100,9 +100,11 @@ module.exports = function (appium) { rest.post('/wd/hub/session/:sessionId?/appium/device/install_app', controller.installApp); rest.post('/wd/hub/session/:sessionId?/appium/device/remove_app', controller.removeApp); rest.post('/wd/hub/session/:sessionId?/appium/device/app_installed', controller.isAppInstalled); + rest.post('/wd/hub/session/:sessionId?/appium/device/hide_keyboard', controller.hideKeyboard); rest.post('/wd/hub/session/:sessionId?/appium/device/push_file', controller.pushFile); rest.post('/wd/hub/session/:sessionId?/appium/device/pull_file', controller.pullFile); rest.post('/wd/hub/session/:sessionId?/appium/device/toggle_airplane_mode', controller.toggleFlightMode); + rest.post('/wd/hub/session/:sessionId?/appium/device/toggle_data', controller.toggleData); 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); diff --git a/test/functional/android/apidemos/attributes-specs.js b/test/functional/android/apidemos/attributes-specs.js index 2d1ee164c..1476617ac 100644 --- a/test/functional/android/apidemos/attributes-specs.js +++ b/test/functional/android/apidemos/attributes-specs.js @@ -70,9 +70,9 @@ describe("apidemos - attributes -", function () { // TODO: fix that, the second scroll doesn't scroll far enough. it('should be able to get selected value of a tab @skip-android-all', function (done) { driver - .execute("mobile: find", [["scroll", [[3, "views"]], [[7, "views"]]]]).click() - .execute("mobile: find", [["scroll", [[3, "tabs"]], [[7, "tabs"]]]]).click() - .execute("mobile: find", [["scroll", [[3, "content by id"]], [[7, "content by id"]]]]).click() + .complexFind(["scroll", [[3, "views"]], [[7, "views"]]]).click() + .complexFind(["scroll", [[3, "tabs"]], [[7, "tabs"]]]).click() + .complexFind(["scroll", [[3, "content by id"]], [[7, "content by id"]]]).click() .elementsByTagName("text").then(function (els) { els[0].getAttribute('selected').should.become('false'); // the 1st text is not selected els[1].getAttribute('selected').should.become('true'); // tab 1 is selected diff --git a/test/functional/android/apidemos/basic-specs.js b/test/functional/android/apidemos/basic-specs.js index ed4746eb0..4d1f91ec3 100644 --- a/test/functional/android/apidemos/basic-specs.js +++ b/test/functional/android/apidemos/basic-specs.js @@ -24,9 +24,8 @@ describe("apidemo - basic -", function () { setup(this, desired).then(function (d) { driver = d; }); it('should die with short command timeout', function (done) { - var params = {timeout: 3}; driver - .execute("mobile: setCommandTimeout", [params]) + .setCommandTimeout(3000) .sleep(4000) .elementByName('Animation') .should.be.rejectedWith(/status: (13|6)/) @@ -47,9 +46,8 @@ describe("apidemo - basic -", function () { .then(find); } }; - var params = {timeout: 7}; driver - .execute("mobile: setCommandTimeout", [params]) + .setCommandTimeout(7000) .then(function () { start = Date.now(); }) .then(find) .sleep(10000) @@ -72,7 +70,7 @@ describe("apidemo - basic -", function () { it('should be able to get current activity', function (done) { driver - .execute("mobile: currentActivity") + .getCurrentActivity() .should.eventually.include("ApiDemos") .nodeify(done); }); @@ -93,22 +91,22 @@ describe("apidemo - basic -", function () { it('should be able to detect if app is installed', function (done) { driver - .execute('mobile: isAppInstalled', [{bundleId: 'foo'}]) + .isAppInstalled('foo') .should.eventually.equal(false) - .execute('mobile: isAppInstalled', [{bundleId: 'com.example.android.apis'}]) + .isAppInstalled('com.example.android.apis') .should.eventually.equal(true) .nodeify(done); }); it("should background the app", function (done) { var before = new Date().getTime() / 1000; driver - .execute("mobile: background", [{seconds: 3}]) + .backgroundApp(3) .then(function () { ((new Date().getTime() / 1000) - before).should.be.least(3); // should really not be checking this. //((new Date().getTime() / 1000) - before).should.be.below(5); }) - .execute("mobile: currentActivity") + .getCurrentActivity() .should.eventually.include("ApiDemos") .nodeify(done); }); @@ -122,7 +120,7 @@ describe("apidemo - basic -", function () { it('should still be able to reset', function (done) { driver .sleep(3000) - .execute('mobile: reset') + .resetApp() .getWindowSize() .nodeify(done); }); diff --git a/test/functional/android/apidemos/file-specs.js b/test/functional/android/apidemos/file-specs.js index c5d2c3472..84c85806f 100644 --- a/test/functional/android/apidemos/file-specs.js +++ b/test/functional/android/apidemos/file-specs.js @@ -1,8 +1,7 @@ "use strict"; var setup = require("../../common/setup-base") - , desired = require("./desired") - , fs = require('fs'); + , desired = require("./desired"); describe("apidemos - push & pull file -", function () { var driver; @@ -13,14 +12,13 @@ describe("apidemos - push & pull file -", function () { var base64Data = new Buffer(stringData).toString('base64'); var remotePath = '/data/local/tmp/remote.txt'; - driver.execute("mobile: pushFile", [{data: base64Data, path: remotePath}]) - .then(function () { - return driver.execute("mobile: pullFile", [{path: remotePath}]); - }) + driver + .pushFile(remotePath, base64Data) + .pullFile(remotePath) .then(function (remoteData64) { var remoteData = new Buffer(remoteData64, 'base64').toString(); remoteData.should.equal(stringData); }) .nodeify(done); }); -}); \ No newline at end of file +}); diff --git a/test/functional/android/apidemos/find-element-specs.js b/test/functional/android/apidemos/find-element-specs.js index 2d2d3e1ad..3a890d9c4 100644 --- a/test/functional/android/apidemos/find-element-specs.js +++ b/test/functional/android/apidemos/find-element-specs.js @@ -19,17 +19,17 @@ describe("apidemo - find elements -", function () { describe('mobile find', function () { it('should scroll to an element by text or content desc', function (done) { driver - .execute("mobile: find", [["scroll", [[3, "views"]], [[7, "views"]]]]).text() + .complexFind(["scroll", [[3, "views"]], [[7, "views"]]]).text() .should.become("Views") .nodeify(done); }); it('should find a single element by content-description', function (done) { - driver.execute("mobile: find", [[[[7, "Animation"]]]]).text() + driver.complexFind([[[7, "Animation"]]]).text() .should.become("Animation") .nodeify(done); }); it('should find a single element by text', function (done) { - driver.execute("mobile: find", [[[[3, "Animation"]]]]).text() + driver.complexFind([[[3, "Animation"]]]).text() .should.become("Animation") .nodeify(done); }); @@ -81,7 +81,7 @@ describe("apidemo - find elements -", function () { }); it('should find a single element by id', function (done) { driver - .execute("mobile: find", [["scroll", [[3, "views"]], [[7, "views"]]]]).click() + .complexFind(["scroll", [[3, "views"]], [[7, "views"]]]).click() .elementByXPath("//android.widget.TextView[@text='Buttons']").click() .elementById("buttons_1_normal").text().should.become("Normal") .nodeify(done); diff --git a/test/functional/android/apidemos/gestures-specs.js b/test/functional/android/apidemos/gestures-specs.js index 166ef5d18..dc35b30de 100644 --- a/test/functional/android/apidemos/gestures-specs.js +++ b/test/functional/android/apidemos/gestures-specs.js @@ -13,7 +13,7 @@ describe("apidemo - gestures -", function () { if (env.FAST_TESTS) { beforeEach(function (done) { - driver.execute("mobile: reset") + driver.resetApp() .then(function () { return driver.sleep(3000); }) .nodeify(done); }); diff --git a/test/functional/android/apidemos/screenshot-specs.js b/test/functional/android/apidemos/screenshot-specs.js index 8c7211296..c905e3d67 100644 --- a/test/functional/android/apidemos/screenshot-specs.js +++ b/test/functional/android/apidemos/screenshot-specs.js @@ -14,10 +14,10 @@ describe("apidemos - screenshot -", function () { }); it('should not cause other commands to fail', function (done) { driver - .execute("mobile: find", [[[[3, "Animation"]]]]) + .complexFind([[[3, "Animation"]]]) .takeScreenshot() .should.eventually.have.length.above(1000) - .execute("mobile: find", [[[[3, "Animation"]]]]) + .complexFind([[[3, "Animation"]]]) .should.eventually.exist .sleep(5000) // cooldown .nodeify(done); diff --git a/test/functional/android/apidemos/source-specs.js b/test/functional/android/apidemos/source-specs.js index d212497a8..93b2d0af1 100644 --- a/test/functional/android/apidemos/source-specs.js +++ b/test/functional/android/apidemos/source-specs.js @@ -26,11 +26,11 @@ describe("apidemos - source -", function () { }); it('should return the page source without crashing other commands', function (done) { driver - .execute("mobile: find", [[[[3, "Animation"]]]]) + .complexFind([[[3, "Animation"]]]) .source().then(function (source) { assertSource(source); }) - .execute("mobile: find", [[[[3, "Animation"]]]]) + .complexFind([[[3, "Animation"]]]) .nodeify(done); }); }); diff --git a/test/functional/android/toggle-specs.js b/test/functional/android/toggle-specs.js index c1c7f8546..7eec8c625 100644 --- a/test/functional/android/toggle-specs.js +++ b/test/functional/android/toggle-specs.js @@ -24,7 +24,7 @@ var toggleTest = function (promisedBrowser, displayName, toggleElementName, togg driver .elementByName(toggleElementName).text().then(function (txt) { initialValue = txt; - return driver.execute("mobile: " + toggleMethod); + return driver[toggleMethod](); }) .then(function () { return driver.elementByName(toggleElementName).text().then(function (txt) { diff --git a/test/functional/ios/file-movement-specs.js b/test/functional/ios/file-movement-specs.js index 39679eea6..84d662882 100644 --- a/test/functional/ios/file-movement-specs.js +++ b/test/functional/ios/file-movement-specs.js @@ -16,18 +16,17 @@ describe('pullFile', function () { setup(this, desired).then(function (d) { driver = d; }); it('should be able to fetch the Address book', function (done) { - var args = {path: 'Library/AddressBook/AddressBook.sqlitedb'}; driver - .execute('mobile: pullFile', [args]).then(function (data) { + .pullFile('Library/AddressBook/AddressBook.sqlitedb') + .then(function (data) { var stringData = new Buffer(data, 'base64').toString(); return stringData.indexOf('SQLite').should.not.equal(-1); }) .nodeify(done); }); it('should not be able to fetch something that does not exist', function (done) { - var args = {path: 'Library/AddressBook/nothere.txt'}; driver - .execute('mobile: pullFile', [args]) + .pullFile('Library/AddressBook/nothere.txt') .should.eventually.be.rejectedWith(/13/) .nodeify(done); }); @@ -61,13 +60,14 @@ describe('pullFile', function () { } }); it('should be able to fetch a file from the app directory', function (done) { - var args = {path: path.resolve('/testapp.app', fileName)}; + var arg = path.resolve('/testapp.app', fileName); driver - .execute('mobile: pullFile', [args]).then(function (data) { + .pullFile(arg) + .then(function (data) { var stringData = new Buffer(data, 'base64').toString(); return stringData.should.equal(fileContent); }) - .nodeify(done); + .nodeify(done); }); }); }); diff --git a/test/functional/ios/testapp/basic-specs.js b/test/functional/ios/testapp/basic-specs.js index 5c2a98260..090dc1c6e 100644 --- a/test/functional/ios/testapp/basic-specs.js +++ b/test/functional/ios/testapp/basic-specs.js @@ -41,10 +41,7 @@ describe('testapp - basic -', function () { if (type === "elem") { return function () { return elem.sendKeys(val); }; } else if (type === "elem-setvalue") { - return function () { - return driver.execute("mobile: setValue", - [{element: elem.value, value: val}]); - }; + return function () { return elem.setImmediateValue(val); }; } else if (type === "driver") { return function () { return elem.click().keys(val); }; } diff --git a/test/functional/ios/testapp/clear-specs.js b/test/functional/ios/testapp/clear-specs.js index c45eddd96..f82196d72 100644 --- a/test/functional/ios/testapp/clear-specs.js +++ b/test/functional/ios/testapp/clear-specs.js @@ -26,7 +26,7 @@ describe('testapp - clear -', function () { .should.be.rejected; } }) - .execute("mobile: hideKeyboard") + .hideKeyboard() .elementByTagName('slider').click() .nodeify(done); }); @@ -41,7 +41,7 @@ describe('testapp - clear -', function () { .should.be.rejected; } }) - .execute("mobile: hideKeyboard", [{keyName: "Done"}]) + .hideKeyboard() .elementByTagName('slider').click() .nodeify(done); }); diff --git a/test/functional/ios/testapp/device-specs.js b/test/functional/ios/testapp/device-specs.js index 4252bc4c7..e8f9c0c25 100644 --- a/test/functional/ios/testapp/device-specs.js +++ b/test/functional/ios/testapp/device-specs.js @@ -1,4 +1,3 @@ -/*globals should:true */ "use strict"; var setup = require("../../common/setup-base"), @@ -17,7 +16,7 @@ describe('testapp - device -', function () { driver .sleep(5000) .then(function () { before = new Date().getTime() / 1000; }) - .execute("mobile: background", [{seconds: 1}]) + .backgroundApp(1) .catch(function (err) { err.cause.value.message.should.contain("Instruments died"); throw err; diff --git a/test/functional/ios/testapp/rotation-gesture-specs.js b/test/functional/ios/testapp/rotation-gesture-specs.js index 3d0d770c2..bc58417c4 100644 --- a/test/functional/ios/testapp/rotation-gesture-specs.js +++ b/test/functional/ios/testapp/rotation-gesture-specs.js @@ -13,8 +13,7 @@ describe('testapp - rotation gesture -', function () { .then(function (buttons) { return buttons[5].click(); }) .sleep(1000).then(function () { okIfAlert(driver); }) .elementsByTagName('Map') - .execute("mobile: rotate", [{x: 114, y: 198, duration: 5, radius: 3, - rotation: 220, touchCount: 2}]) + .rotate({x: 114, y: 198, duration: 5, radius: 3, rotation: 220, touchCount: 2}) .nodeify(done); }); }); diff --git a/test/functional/ios/testapp/timeouts-specs.js b/test/functional/ios/testapp/timeouts-specs.js index 12a80214c..5963da8a2 100644 --- a/test/functional/ios/testapp/timeouts-specs.js +++ b/test/functional/ios/testapp/timeouts-specs.js @@ -19,9 +19,8 @@ describe('testapp - timeouts -', function () { setup(this, desired).then(function (d) { driver = d; }); it('should die with short command timeout', function (done) { - var params = {timeout: 3}; driver - .execute("mobile: setCommandTimeout", [params]) + .setCommandTimeout(3000) .sleep(5500) .elementByName('dont exist dogg') .should.be.rejectedWith(/status: (13|6)/) @@ -34,10 +33,9 @@ describe('testapp - timeouts -', function () { setup(this, desired).then(function (d) { driver = d; }); it('should die with short command timeout even after mobile reset', function (done) { - var params = {timeout: 3}; driver - .execute("mobile: setCommandTimeout", [params]) - .execute("mobile: reset") + .setCommandTimeout(3000) + .resetApp() .sleep(6500) .elementByName('dont exist dogg') .should.be.rejectedWith(/status: (13|6)/) @@ -51,20 +49,7 @@ describe('testapp - timeouts -', function () { it('when set to 0 should disable itself', function (done) { driver - .execute("mobile: setCommandTimeout", [{timeout: 0}]) - .sleep(3000) - .elementByTagName('button').should.eventually.exist - .nodeify(done); - }); - }); - - describe('command timeout set to false', function () { - var driver; - setup(this, desired).then(function (d) { driver = d; }); - - it('when set to false should disable itself', function (done) { - driver - .execute("mobile: setCommandTimeout", [{timeout: false}]) + .setCommandTimeout(0) .sleep(3000) .elementByTagName('button').should.eventually.exist .nodeify(done); @@ -85,33 +70,6 @@ describe('testapp - timeouts -', function () { }); }); - describe('command timeout disabled via desired caps (0)', function () { - var driver; - setup(this, _.defaults({newCommandTimeout: 0}, desired)) - .then(function (d) { driver = d; }); - - it('when set to 0 should disable itself', function (done) { - driver - .sleep(5000) - .elementByTagName('button').should.eventually.exist - .nodeify(done); - }); - }); - - describe('command timeout disabled via desired caps (false)', function () { - var driver; - setup(this, _.defaults({newCommandTimeout: false}, desired)) - .then(function (d) { driver = d; }); - - it('when set to false should disable itself', function (done) { - driver - .execute("mobile: setCommandTimeout", [{timeout: false}]) - .sleep(5000) - .elementByTagName('button').should.eventually.exist - .nodeify(done); - }); - }); - describe('check implicit wait', function () { var driver; setup(this, desired).then(function (d) { driver = d; }); @@ -139,7 +97,7 @@ describe('testapp - timeouts -', function () { driver .setImplicitWaitTimeout(impWaitSecs * 1000) .then(impWaitCheck) - .execute("mobile: reset") + .resetApp() .sleep(3000) // cooldown .then(impWaitCheck) .nodeify(done); diff --git a/test/functional/ios/uicatalog/device-specs.js b/test/functional/ios/uicatalog/device-specs.js index 0b6ced8cd..bcdac802b 100644 --- a/test/functional/ios/uicatalog/device-specs.js +++ b/test/functional/ios/uicatalog/device-specs.js @@ -13,7 +13,7 @@ describe('uicatalog - device -', function () { it("should lock the device for 4 of seconds (+/- " + allowance + " secs)", function (done) { var before = new Date().getTime() / 1000; driver - .execute("mobile: lock", [{seconds: 4}]) + .lockDevice(4) .then(function () { var now = (new Date().getTime() / 1000); (now - before).should.be.above(4); @@ -27,7 +27,7 @@ describe('uicatalog - device -', function () { it("should background the app for 4 of seconds (+/- 6 secs)", function (done) { var before = new Date().getTime() / 1000; driver - .execute("mobile: background", [{seconds: 4}]) + .backgroundApp(4) .then(function () { ((new Date().getTime() / 1000) - before).should.be.below(11); }).nodeify(done); diff --git a/test/functional/ios/uicatalog/gestures-specs.js b/test/functional/ios/uicatalog/gestures-specs.js index a4d084131..ee835b566 100644 --- a/test/functional/ios/uicatalog/gestures-specs.js +++ b/test/functional/ios/uicatalog/gestures-specs.js @@ -482,8 +482,7 @@ describe('uicatalog - gestures -', function () { setup(this, desired).then(function (d) { driver = d; }); it('should not error', function (done) { - driver.execute('mobile: shake') - .nodeify(done); + driver.shakeDevice().nodeify(done); }); }); diff --git a/test/functional/ios/uicatalog/reset-specs.js b/test/functional/ios/uicatalog/reset-specs.js index 44748c433..f5c566a3d 100644 --- a/test/functional/ios/uicatalog/reset-specs.js +++ b/test/functional/ios/uicatalog/reset-specs.js @@ -13,7 +13,7 @@ describe('uicatalog - reset -', function () { driver .elementsByTagName('tableView') .should.eventually.have.length(1) - .execute("mobile: reset") + .resetApp() .sleep(3000) .elementsByTagName('tableView') .should.eventually.have.length(1) diff --git a/test/functional/selendroid/basic-specs.js b/test/functional/selendroid/basic-specs.js index 9f04fa95b..f731c7bfa 100644 --- a/test/functional/selendroid/basic-specs.js +++ b/test/functional/selendroid/basic-specs.js @@ -73,7 +73,7 @@ describe('selendroid - basic -', function () { it('should be able to uninstall the app', function (done) { driver - .execute("mobile: removeApp", [{bundleId: "com.example.android.apis"}]) + .removeApp("com.example.android.apis") .nodeify(done); }); }); @@ -85,13 +85,13 @@ describe('selendroid - basic -', function () { it("should background the app", function (done) { var before = new Date().getTime() / 1000; driver - .execute("mobile: background", [{seconds: 3}]) + .backgroundApp(3) .then(function () { ((new Date().getTime() / 1000) - before).should.be.above(2); // this should not be tested // ((new Date().getTime() / 1000) - before).should.be.below(5); }) - .execute("mobile: currentActivity") + .getCurrentActivity() .should.eventually.include("ApiDemos") .nodeify(done); });