diff options
Diffstat (limited to 'dom/system/gonk/tests/marionette/head.js')
-rw-r--r-- | dom/system/gonk/tests/marionette/head.js | 345 |
1 files changed, 345 insertions, 0 deletions
diff --git a/dom/system/gonk/tests/marionette/head.js b/dom/system/gonk/tests/marionette/head.js new file mode 100644 index 000000000..5a6ee1272 --- /dev/null +++ b/dom/system/gonk/tests/marionette/head.js @@ -0,0 +1,345 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +MARIONETTE_CONTEXT = "chrome"; + +const SETTINGS_KEY_DATA_ENABLED = "ril.data.enabled"; +const SETTINGS_KEY_DATA_APN_SETTINGS = "ril.data.apnSettings"; +const SETTINGS_KEY_WIFI_ENABLED = "wifi.enabled"; + +const TOPIC_CONNECTION_STATE_CHANGED = "network-connection-state-changed"; +const TOPIC_NETWORK_ACTIVE_CHANGED = "network-active-changed"; + +const NETWORK_STATE_UNKNOWN = Ci.nsINetworkInfo.NETWORK_STATE_UNKNOWN; +const NETWORK_STATE_CONNECTING = Ci.nsINetworkInfo.NETWORK_STATE_CONNECTING; +const NETWORK_STATE_CONNECTED = Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED; +const NETWORK_STATE_DISCONNECTING = Ci.nsINetworkInfo.NETWORK_STATE_DISCONNECTING; +const NETWORK_STATE_DISCONNECTED = Ci.nsINetworkInfo.NETWORK_STATE_DISCONNECTED; + +const NETWORK_TYPE_MOBILE = Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE; +const NETWORK_TYPE_MOBILE_MMS = Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_MMS; +const NETWORK_TYPE_MOBILE_SUPL = Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_SUPL; +const NETWORK_TYPE_MOBILE_IMS = Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_IMS; +const NETWORK_TYPE_MOBILE_DUN = Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_DUN; +const NETWORK_TYPE_MOBILE_FOTA = Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_FOTA; + +const networkTypes = [ + NETWORK_TYPE_MOBILE, + NETWORK_TYPE_MOBILE_MMS, + NETWORK_TYPE_MOBILE_SUPL, + NETWORK_TYPE_MOBILE_IMS, + NETWORK_TYPE_MOBILE_DUN, + NETWORK_TYPE_MOBILE_FOTA +]; + +var Promise = Cu.import("resource://gre/modules/Promise.jsm").Promise; + +var ril = Cc["@mozilla.org/ril;1"].getService(Ci.nsIRadioInterfaceLayer); +ok(ril, "ril.constructor is " + ril.constructor); + +var radioInterface = ril.getRadioInterface(0); +ok(radioInterface, "radioInterface.constructor is " + radioInterface.constrctor); + +var _pendingEmulatorShellCmdCount = 0; +var _pendingEmulatorCmdCount = 0; + +/** + * Send emulator shell command with safe guard. + * + * We should only call |finish()| after all emulator shell command transactions + * end, so here comes with the pending counter. Resolve when the emulator + * shell gives response. Never reject. + * + * Fulfill params: + * result -- an array of emulator shell response lines. + * + * @param aCommands + * A string array commands to be passed to emulator through adb shell. + * + * @return A deferred promise. + */ +function runEmulatorShellCmdSafe(aCommands) { + return new Promise(function(aResolve, aReject) { + ++_pendingEmulatorShellCmdCount; + runEmulatorShell(aCommands, function(aResult) { + --_pendingEmulatorShellCmdCount; + + log("Emulator shell response: " + JSON.stringify(aResult)); + aResolve(aResult); + }); + }); +} + +/** + * Send emulator command with safe guard. + * + * We should only call |finish()| after all emulator command transactions + * end, so here comes with the pending counter. Resolve when the emulator + * gives positive response, and reject otherwise. + * + * Fulfill params: + * result -- an array of emulator response lines. + * Reject params: + * result -- an array of emulator response lines. + * + * @param aCommand + * A string command to be passed to emulator through its telnet console. + * + * @return A deferred promise. + */ +function runEmulatorCmdSafe(aCommand) { + log(aCommand); + return new Promise(function(aResolve, aReject) { + ++_pendingEmulatorCmdCount; + runEmulatorCmd(aCommand, function(aResult) { + --_pendingEmulatorCmdCount; + + log("Emulator console response: " + JSON.stringify(aResult)); + if (Array.isArray(aResult) && + aResult[aResult.length - 1] === "OK") { + aResolve(aResult); + } else { + aReject(aResult); + } + }); + }); +} + +/** + * Get mozSettings value specified by @aKey. + * + * Resolve if that mozSettings value is retrieved successfully, reject + * otherwise. + * + * Fulfill params: The corresponding mozSettings value of the key. + * Reject params: (none) + * + * @param aKey + * A string. + * @param aAllowError [optional] + * A boolean value. If set to true, an error response won't be treated + * as test failure. Default: false. + * + * @return A deferred promise. + */ +function getSettings(aKey, aAllowError) { + let request = window.navigator.mozSettings.createLock().get(aKey); + return request.then(function resolve(aValue) { + log("getSettings(" + aKey + ") - success"); + return aValue[aKey]; + }, function reject(aError) { + ok(aAllowError, "getSettings(" + aKey + ") - error"); + }); +} + +/** + * Set mozSettings values. + * + * Resolve if that mozSettings value is set successfully, reject otherwise. + * + * Fulfill params: (none) + * Reject params: (none) + * + * @param aKey + * A string key. + * @param aValue + * An object value. + * @param aAllowError [optional] + * A boolean value. If set to true, an error response won't be treated + * as test failure. Default: false. + * + * @return A deferred promise. + */ +function setSettings(aKey, aValue, aAllowError) { + let settings = {}; + settings[aKey] = aValue; + let lock = window.navigator.mozSettings.createLock(); + let request = lock.set(settings); + let deferred = Promise.defer(); + lock.onsettingstransactionsuccess = function () { + log("setSettings(" + JSON.stringify(settings) + ") - success"); + deferred.resolve(); + }; + lock.onsettingstransactionfailure = function () { + ok(aAllowError, "setSettings(" + JSON.stringify(settings) + ") - error"); + // We resolve even though we've thrown an error, since the ok() + // will do that. + deferred.resolve(); + }; + return deferred.promise; +} + +/** + * Wait for observer event. + * + * Resolve if that topic event occurs. Never reject. + * + * Fulfill params: the subject passed. + * + * @param aTopic + * A string topic name. + * + * @return A deferred promise. + */ +function waitForObserverEvent(aTopic) { + let obs = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService); + let deferred = Promise.defer(); + + obs.addObserver(function observer(subject, topic, data) { + if (topic === aTopic) { + obs.removeObserver(observer, aTopic); + deferred.resolve(subject); + } + }, aTopic, false); + + return deferred.promise; +} + +/** + * Wait for one named event. + * + * Resolve if that named event occurs. Never reject. + * + * Fulfill params: the DOMEvent passed. + * + * @param aEventTarget + * An EventTarget object. + * @param aEventName + * A string event name. + * @param aMatchFun [optional] + * A matching function returns true or false to filter the event. + * + * @return A deferred promise. + */ +function waitForTargetEvent(aEventTarget, aEventName, aMatchFun) { + return new Promise(function(aResolve, aReject) { + aEventTarget.addEventListener(aEventName, function onevent(aEvent) { + if (!aMatchFun || aMatchFun(aEvent)) { + aEventTarget.removeEventListener(aEventName, onevent); + ok(true, "Event '" + aEventName + "' got."); + aResolve(aEvent); + } + }); + }); +} + +/** + * Set the default data connection enabling state, wait for + * "network-connection-state-changed" event and verify state. + * + * Fulfill params: instance of nsIRilNetworkInfo of the network connected. + * + * @param aEnabled + * A boolean state. + * + * @return A deferred promise. + */ +function setDataEnabledAndWait(aEnabled) { + let promises = []; + promises.push(waitForObserverEvent(TOPIC_CONNECTION_STATE_CHANGED) + .then(function(aSubject) { + ok(aSubject instanceof Ci.nsIRilNetworkInfo, + "subject should be an instance of nsIRilNetworkInfo"); + is(aSubject.type, NETWORK_TYPE_MOBILE, + "subject.type should be " + NETWORK_TYPE_MOBILE); + is(aSubject.state, + aEnabled ? Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED + : Ci.nsINetworkInfo.NETWORK_STATE_DISCONNECTED, + "subject.state should be " + aEnabled ? "CONNECTED" : "DISCONNECTED"); + + return aSubject; + })); + promises.push(setSettings(SETTINGS_KEY_DATA_ENABLED, aEnabled)); + + return Promise.all(promises).then(aValues => aValues[0]); +} + +/** + * Setup a certain type of data connection, wait for + * "network-connection-state-changed" event and verify state. + * + * Fulfill params: instance of nsIRilNetworkInfo of the network connected. + * + * @param aNetworkType + * The mobile network type to setup. + * + * @return A deferred promise. + */ +function setupDataCallAndWait(aNetworkType) { + log("setupDataCallAndWait: " + aNetworkType); + + let promises = []; + promises.push(waitForObserverEvent(TOPIC_CONNECTION_STATE_CHANGED) + .then(function(aSubject) { + ok(aSubject instanceof Ci.nsIRilNetworkInfo, + "subject should be an instance of nsIRilNetworkInfo"); + is(aSubject.type, aNetworkType, + "subject.type should be " + aNetworkType); + is(aSubject.state, Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED, + "subject.state should be CONNECTED"); + + return aSubject; + })); + promises.push(radioInterface.setupDataCallByType(aNetworkType)); + + return Promise.all(promises).then(aValues => aValues[0]); +} + +/** + * Deactivate a certain type of data connection, wait for + * "network-connection-state-changed" event and verify state. + * + * Fulfill params: (none) + * + * @param aNetworkType + * The mobile network type to deactivate. + * + * @return A deferred promise. + */ +function deactivateDataCallAndWait(aNetworkType) { + log("deactivateDataCallAndWait: " + aNetworkType); + + let promises = []; + promises.push(waitForObserverEvent(TOPIC_CONNECTION_STATE_CHANGED) + .then(function(aSubject) { + ok(aSubject instanceof Ci.nsIRilNetworkInfo, + "subject should be an instance of nsIRilNetworkInfo"); + is(aSubject.type, aNetworkType, + "subject.type should be " + aNetworkType); + is(aSubject.state, Ci.nsINetworkInfo.NETWORK_STATE_DISCONNECTED, + "subject.state should be DISCONNECTED"); + })); + promises.push(radioInterface.deactivateDataCallByType(aNetworkType)); + + return Promise.all(promises); +} + +/** + * Wait for pending emulator transactions and call |finish()|. + */ +function cleanUp() { + // Use ok here so that we have at least one test run. + ok(true, ":: CLEANING UP ::"); + + waitFor(finish, function() { + return _pendingEmulatorShellCmdCount === 0 && + _pendingEmulatorCmdCount === 0; + }); +} + +/** + * Basic test routine helper. + * + * This helper does nothing but clean-ups. + * + * @param aTestCaseMain + * A function that takes no parameter. + */ +function startTestBase(aTestCaseMain) { + Promise.resolve() + .then(aTestCaseMain) + .then(cleanUp, function(aException) { + ok(false, "promise rejects during test: " + aException); + cleanUp(); + }); +} |