Bug 940554 - Fix Marionette's newSession to return capabilities. r=mdas

This commit is contained in:
Andreas Tolfsen 2014-01-28 17:54:44 -05:00
parent 403d9710cc
commit b60f2a333a
4 changed files with 87 additions and 41 deletions

View File

@ -576,39 +576,40 @@ class Marionette(object):
time.sleep(1)
return False
def _send_message(self, command, response_key, **kwargs):
if not self.session and command not in ('newSession', 'getStatus'):
raise MarionetteException(message="Please start a session")
def _send_message(self, command, response_key="ok", **kwargs):
if not self.session and command not in ("newSession", "getStatus"):
raise MarionetteException("Please start a session")
message = { 'name': command }
message = {"name": command}
if self.session:
message['sessionId'] = self.session
message["sessionId"] = self.session
if kwargs:
message['parameters'] = kwargs
message["parameters"] = kwargs
try:
response = self.client.send(message)
except socket.timeout:
except socket.timeout as e:
self.session = None
self.window = None
self.client.close()
raise TimeoutException(message='socket.timeout', status=ErrorCodes.TIMEOUT, stacktrace=None)
raise TimeoutException(
"Connection timed out", status=ErrorCodes.TIMEOUT,
cause=e)
# 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:
if response_key in response:
return response[response_key]
else:
self._handle_error(response)
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.")
raise MarionetteException(
"No emulator in this test to run command against")
cmd = cmd.encode("ascii")
result = self.emulator._run_telnet(cmd)
return self.client.send({"name": "emulatorCmdResult",
@ -699,11 +700,17 @@ class Marionette(object):
return self._send_message('getStatus', 'value')
def start_session(self, desired_capabilities=None):
'''
Creates a new Marionette session.
"""Create a new Marionette session.
This method must be called before performing any other action.
:params desired_capabilities: An optional dict of desired
capabilities. This is currently ignored.
:returns: A dict of the capabilities offered.
"""
You must call this method before performing any other action.
'''
try:
# We are ignoring desired_capabilities, at least for now.
self.session = self._send_message('newSession', 'value')

View File

@ -0,0 +1,32 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import marionette_test
class TestSession(marionette_test.MarionetteTestCase):
def setUp(self):
super(TestSession, self).setUp()
self.marionette.delete_session()
def test_new_session_returns_capabilities(self):
# Sends newSession
caps = self.marionette.start_session()
# Check that session was created. This implies the server
# sent us the sessionId and status fields.
self.assertIsNotNone(self.marionette.session)
# Required capabilities mandated by WebDriver spec
self.assertIn("browserName", caps)
self.assertIn("platformName", caps)
self.assertIn("platformVersion", caps)
# Optional capabilities we want Marionette to support
self.assertIn("cssSelectorsEnabled", caps)
self.assertIn("device", caps)
self.assertIn("handlesAlerts", caps)
self.assertIn("javascriptEnabled", caps)
self.assertIn("rotatable", caps)
self.assertIn("takesScreenshot", caps)
self.assertIn("version", caps)

View File

@ -11,6 +11,8 @@ b2g = true
; true if the test should be skipped
skip = false
[test_session.py]
[test_expectedfail.py]
expected = fail
[test_getstatus.py]

View File

@ -489,11 +489,14 @@ MarionetteServerConnection.prototype = {
*/
/**
* Create a new session. This creates a BrowserObj.
* Create a new session. This creates a new BrowserObj.
*
* In a desktop environment, this opens a new 'about:blank' tab for
* the client to test in.
* In a desktop environment, this opens a new browser with
* "about:blank" which subsequent commands will be sent to.
*
* This will send a hash map of supported capabilities to the client
* as part of the Marionette:register IPC command in the
* receiveMessage callback when a new browser is created.
*/
newSession: function MDA_newSession() {
this.command_id = this.getCommandId();
@ -507,25 +510,27 @@ MarionetteServerConnection.prototype = {
if (!win ||
(appName == "Firefox" && !win.gBrowser) ||
(appName == "Fennec" && !win.BrowserApp)) {
checkTimer.initWithCallback(waitForWindow.bind(this), 100, Ci.nsITimer.TYPE_ONE_SHOT);
checkTimer.initWithCallback(waitForWindow.bind(this), 100,
Ci.nsITimer.TYPE_ONE_SHOT);
}
else {
this.startBrowser(win, true);
}
}
if (!Services.prefs.getBoolPref("marionette.contentListener")) {
waitForWindow.call(this);
}
else if ((appName != "Firefox") && (this.curBrowser == null)) {
//if there is a content listener, then we just wake it up
// If there is a content listener, then we just wake it up
this.addBrowser(this.getCurrentWindow());
this.curBrowser.startSession(false, this.getCurrentWindow(), this.whenBrowserStarted);
this.curBrowser.startSession(false, this.getCurrentWindow(),
this.whenBrowserStarted);
this.messageManager.broadcastAsyncMessage("Marionette:restart", {});
}
else {
this.sendError("Session already running", 500, null, this.command_id);
this.sendError("Session already running", 500, null,
this.command_id);
}
this.switchToGlobalMessageManager();
},
@ -536,21 +541,21 @@ MarionetteServerConnection.prototype = {
let rotatable = appName == "B2G" ? true : false;
let value = {
'appBuildId' : Services.appinfo.appBuildID,
'XULappId' : Services.appinfo.ID,
'cssSelectorsEnabled': true,
'browserName': appName,
'handlesAlerts': false,
'javascriptEnabled': true,
'nativeEvents': false,
'platformName': Services.appinfo.OS,
'platformVersion': Services.appinfo.platformVersion,
'secureSsl': false,
'device': qemu == "1" ? "qemu" : (!device ? "desktop" : device),
'rotatable': rotatable,
'takesScreenshot': true,
'takesElementScreenshot': true,
'version': Services.appinfo.version
'appBuildId' : Services.appinfo.appBuildID,
'XULappId' : Services.appinfo.ID,
'cssSelectorsEnabled': true,
'browserName': appName,
'handlesAlerts': false,
'javascriptEnabled': true,
'nativeEvents': false,
'platformName': Services.appinfo.OS,
'platformVersion': Services.appinfo.platformVersion,
'secureSsl': false,
'device': qemu == "1" ? "qemu" : (!device ? "desktop" : device),
'rotatable': rotatable,
'takesScreenshot': true,
'takesElementScreenshot': true,
'version': Services.appinfo.version
};
this.sendResponse(value, this.command_id);
@ -2387,7 +2392,7 @@ MarionetteServerConnection.prototype = {
return;
}
if (this.curBrowser.newSession) {
this.sendResponse(reg.id, this.newSessionCommandId);
this.getSessionCapabilities();
this.newSessionCommandId = null;
}
}