mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 06:11:37 +00:00
Bug 754216 - Control the emulator from within Marionette JS scripts. r=jgriffin DONTBUILD because NPOTB
This commit is contained in:
parent
370603a9a2
commit
cf43882096
@ -169,11 +169,27 @@ class Marionette(object):
|
||||
self.port = self.client.port = port
|
||||
raise TimeoutException(message='socket.timeout', status=21, stacktrace=None)
|
||||
|
||||
# Process any emulator commands that are sent from a script
|
||||
# while it's executing.
|
||||
while response.get("emulator_cmd"):
|
||||
response = self._handle_emulator_cmd(response)
|
||||
|
||||
if (response_key == 'ok' and response.get('ok') == True) or response_key in response:
|
||||
return response[response_key]
|
||||
else:
|
||||
self._handle_error(response)
|
||||
|
||||
def _handle_emulator_cmd(self, response):
|
||||
cmd = response.get("emulator_cmd")
|
||||
if not cmd or not self.emulator:
|
||||
raise MarionetteException(message="No emulator in this test to run "
|
||||
"command against.")
|
||||
cmd = cmd.encode("ascii")
|
||||
result = self.emulator._run_telnet(cmd)
|
||||
return self.client.send({"type": "emulatorCmdResult",
|
||||
"id": response.get("id"),
|
||||
"result": result})
|
||||
|
||||
def _handle_error(self, response):
|
||||
if 'error' in response and isinstance(response['error'], dict):
|
||||
status = response['error'].get('status', 500)
|
||||
|
@ -151,6 +151,10 @@ class MarionetteJSTestCase(CommonTestCase):
|
||||
context = context.group(3)
|
||||
self.marionette.set_context(context)
|
||||
|
||||
if context != "chrome":
|
||||
page = self.marionette.absolute_url("empty.html")
|
||||
self.marionette.navigate(page)
|
||||
|
||||
timeout = self.timeout_re.search(js)
|
||||
if timeout:
|
||||
timeout = timeout.group(3)
|
||||
|
@ -0,0 +1,20 @@
|
||||
from marionette_test import MarionetteTestCase
|
||||
from errors import JavascriptException, MarionetteException
|
||||
|
||||
class TestEmulatorContent(MarionetteTestCase):
|
||||
|
||||
def test_emulator_cmd(self):
|
||||
self.marionette.set_script_timeout(10000)
|
||||
expected = ["gsm voice state: home",
|
||||
"gsm data state: home",
|
||||
"OK"]
|
||||
result = self.marionette.execute_async_script("""
|
||||
runEmulatorCmd("gsm status", marionetteScriptFinished)
|
||||
""");
|
||||
self.assertEqual(result, expected)
|
||||
|
||||
class TestEmulatorChrome(TestEmulatorContent):
|
||||
|
||||
def setUp(self):
|
||||
super(TestEmulatorChrome, self).setUp()
|
||||
self.marionette.set_context("chrome")
|
@ -7,5 +7,8 @@ MARIONETTE_TIMEOUT = 1000;
|
||||
is(2, 2, "test for is()");
|
||||
isnot(2, 3, "test for isnot()");
|
||||
ok(2 == 2, "test for ok()");
|
||||
|
||||
is(window.location.pathname.slice(-10), "empty.html");
|
||||
|
||||
setTimeout(finish, 100);
|
||||
|
||||
|
@ -10,6 +10,7 @@ b2g = false
|
||||
b2g = false
|
||||
|
||||
[test_log.py]
|
||||
[test_emulator.py]
|
||||
[test_execute_async_script.py]
|
||||
[test_execute_script.py]
|
||||
[test_simpletest_fail.js]
|
||||
|
8
testing/marionette/client/marionette/www/empty.html
Normal file
8
testing/marionette/client/marionette/www/empty.html
Normal file
@ -0,0 +1,8 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Marionette Test</title>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
@ -1,4 +1,4 @@
|
||||
<!doctype html>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Marionette Test</title>
|
||||
|
@ -131,6 +131,7 @@ function MarionetteDriverActor(aConnection)
|
||||
this.messageManager.addMessageListener("Marionette:testLog", this);
|
||||
this.messageManager.addMessageListener("Marionette:register", this);
|
||||
this.messageManager.addMessageListener("Marionette:goUrl", this);
|
||||
this.messageManager.addMessageListener("Marionette:runEmulatorCmd", this);
|
||||
}
|
||||
|
||||
MarionetteDriverActor.prototype = {
|
||||
@ -165,8 +166,13 @@ MarionetteDriverActor.prototype = {
|
||||
*/
|
||||
sendToClient: function MDA_sendToClient(msg, command_id) {
|
||||
logger.info("sendToClient: " + JSON.stringify(msg) + ", " + command_id + ", " + this.command_id);
|
||||
if (command_id == undefined || command_id == this.command_id) {
|
||||
if (this.command_id != null &&
|
||||
command_id != null &&
|
||||
this.command_id != command_id) {
|
||||
return;
|
||||
}
|
||||
this.conn.send(msg);
|
||||
if (command_id != null) {
|
||||
this.command_id = null;
|
||||
}
|
||||
},
|
||||
@ -506,7 +512,7 @@ MarionetteDriverActor.prototype = {
|
||||
}
|
||||
|
||||
let curWindow = this.getCurrentWindow();
|
||||
let marionette = new Marionette(false, curWindow, "chrome", this.marionetteLog);
|
||||
let marionette = new Marionette(this, curWindow, "chrome", this.marionetteLog);
|
||||
let _chromeSandbox = this.createExecuteSandbox(curWindow, marionette, aRequest.args);
|
||||
if (!_chromeSandbox)
|
||||
return;
|
||||
@ -613,7 +619,7 @@ MarionetteDriverActor.prototype = {
|
||||
let curWindow = this.getCurrentWindow();
|
||||
let original_onerror = curWindow.onerror;
|
||||
let that = this;
|
||||
let marionette = new Marionette(true, curWindow, "chrome", this.marionetteLog);
|
||||
let marionette = new Marionette(this, curWindow, "chrome", this.marionetteLog);
|
||||
marionette.command_id = this.command_id;
|
||||
|
||||
function chromeAsyncReturnFunc(value, status) {
|
||||
@ -1181,9 +1187,41 @@ MarionetteDriverActor.prototype = {
|
||||
this.messageManager.removeMessageListener("Marionette:testLog", this);
|
||||
this.messageManager.removeMessageListener("Marionette:register", this);
|
||||
this.messageManager.removeMessageListener("Marionette:goUrl", this);
|
||||
this.messageManager.removeMessageListener("Marionette:runEmulatorCmd", this);
|
||||
this.curBrowser = null;
|
||||
},
|
||||
|
||||
_emu_cb_id: 0,
|
||||
_emu_cbs: null,
|
||||
runEmulatorCmd: function runEmulatorCmd(cmd, callback) {
|
||||
if (typeof callback != "function") {
|
||||
throw "Need to provide callback function!";
|
||||
}
|
||||
if (!this._emu_cbs) {
|
||||
this._emu_cbs = {};
|
||||
}
|
||||
this._emu_cbs[this._emu_cb_id] = callback;
|
||||
this.sendToClient({emulator_cmd: cmd, id: this._emu_cb_id});
|
||||
this._emu_cb_id += 1;
|
||||
},
|
||||
|
||||
emulatorCmdResult: function emulatorCmdResult(message) {
|
||||
if (this.context != "chrome") {
|
||||
this.sendAsync("emulatorCmdResult", message);
|
||||
return;
|
||||
}
|
||||
|
||||
let cb = this._emu_cbs[message.id];
|
||||
delete this._emu_cbs[message.id];
|
||||
try {
|
||||
cb(message.result);
|
||||
}
|
||||
catch(e) {
|
||||
this.sendError(e.message, e.num, e.stack);
|
||||
return;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Receives all messages from content messageManager
|
||||
*/
|
||||
@ -1210,6 +1248,9 @@ MarionetteDriverActor.prototype = {
|
||||
//log messages from tests
|
||||
this.marionetteLog.addLogs(message.json.value);
|
||||
break;
|
||||
case "Marionette:runEmulatorCmd":
|
||||
this.sendToClient(message.json);
|
||||
break;
|
||||
case "Marionette:register":
|
||||
// This code processes the content listener's registration information
|
||||
// and either accepts the listener, or ignores it
|
||||
@ -1269,7 +1310,8 @@ MarionetteDriverActor.prototype.requestTypes = {
|
||||
"getWindows": MarionetteDriverActor.prototype.getWindows,
|
||||
"switchToFrame": MarionetteDriverActor.prototype.switchToFrame,
|
||||
"switchToWindow": MarionetteDriverActor.prototype.switchToWindow,
|
||||
"deleteSession": MarionetteDriverActor.prototype.deleteSession
|
||||
"deleteSession": MarionetteDriverActor.prototype.deleteSession,
|
||||
"emulatorCmdResult": MarionetteDriverActor.prototype.emulatorCmdResult
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -101,6 +101,7 @@ function startListeners() {
|
||||
addMessageListenerId("Marionette:switchToFrame", switchToFrame);
|
||||
addMessageListenerId("Marionette:deleteSession", deleteSession);
|
||||
addMessageListenerId("Marionette:sleepSession", sleepSession);
|
||||
addMessageListenerId("Marionette:emulatorCmdResult", emulatorCmdResult);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -158,6 +159,7 @@ function deleteSession(msg) {
|
||||
removeMessageListenerId("Marionette:switchToFrame", switchToFrame);
|
||||
removeMessageListenerId("Marionette:deleteSession", deleteSession);
|
||||
removeMessageListenerId("Marionette:sleepSession", sleepSession);
|
||||
removeMessageListenerId("Marionette:emulatorCmdResult", emulatorCmdResult);
|
||||
this.elementManager.reset();
|
||||
}
|
||||
|
||||
@ -237,7 +239,7 @@ function createExecuteContentSandbox(aWindow) {
|
||||
sandbox.__proto__ = sandbox.window;
|
||||
sandbox.testUtils = utils;
|
||||
|
||||
let marionette = new Marionette(false, aWindow, "content", marionetteLogObj);
|
||||
let marionette = new Marionette(this, aWindow, "content", marionetteLogObj);
|
||||
sandbox.marionette = marionette;
|
||||
marionette.exports.forEach(function(fn) {
|
||||
sandbox[fn] = marionette[fn].bind(marionette);
|
||||
@ -688,5 +690,29 @@ function switchToFrame(msg) {
|
||||
sandbox = null;
|
||||
}
|
||||
|
||||
let _emu_cb_id = 0;
|
||||
let _emu_cbs = {};
|
||||
function runEmulatorCmd(cmd, callback) {
|
||||
if (typeof callback != "function") {
|
||||
throw "Need to provide callback function!";
|
||||
}
|
||||
_emu_cbs[_emu_cb_id] = callback;
|
||||
sendAsyncMessage("Marionette:runEmulatorCmd", {emulator_cmd: cmd, id: _emu_cb_id});
|
||||
_emu_cb_id += 1;
|
||||
}
|
||||
|
||||
function emulatorCmdResult(msg) {
|
||||
let message = msg.json;
|
||||
let cb = _emu_cbs[message.id];
|
||||
delete _emu_cbs[message.id];
|
||||
try {
|
||||
cb(message.result);
|
||||
}
|
||||
catch(e) {
|
||||
sendError(e.message, e.num, e.stack);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//call register self when we get loaded
|
||||
registerSelf();
|
||||
|
@ -5,8 +5,8 @@
|
||||
* The Marionette object, passed to the script context.
|
||||
*/
|
||||
|
||||
function Marionette(is_async, window, context, logObj) {
|
||||
this.is_async = is_async;
|
||||
function Marionette(scope, window, context, logObj) {
|
||||
this.scope = scope;
|
||||
this.window = window;
|
||||
this.tests = [];
|
||||
this.logObj = logObj;
|
||||
@ -15,7 +15,8 @@ function Marionette(is_async, window, context, logObj) {
|
||||
}
|
||||
|
||||
Marionette.prototype = {
|
||||
exports: ['ok', 'is', 'isnot', 'log', 'getLogs', 'generate_results', 'waitFor'],
|
||||
exports: ['ok', 'is', 'isnot', 'log', 'getLogs', 'generate_results', 'waitFor',
|
||||
'runEmulatorCmd'],
|
||||
|
||||
ok: function Marionette__ok(condition, name, diag) {
|
||||
let test = {'result': !!condition, 'name': name, 'diag': diag};
|
||||
@ -134,5 +135,10 @@ Marionette.prototype = {
|
||||
}
|
||||
this.window.setTimeout(this.waitFor.bind(this), 100, callback, test, timeout);
|
||||
},
|
||||
|
||||
runEmulatorCmd: function runEmulatorCmd(cmd, callback) {
|
||||
this.scope.runEmulatorCmd(cmd, callback);
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user