зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1153832: New dispatch style framework in Marionette listener
Takes advantage of the new dispatching technique introduced in bug 1107706 on the content side. The patch introduces the framework to write simpler command handlers in content space, but does not convert all commands in listener.js to use this. This can be done gradually, as both techniques are still compatible. r=dburns --HG-- extra : rebase_source : 43ef240735099221cbbddb753eaf9e2802a4de1d
This commit is contained in:
Родитель
e4e6d4093d
Коммит
001f9b3793
|
@ -155,8 +155,7 @@ ListenerProxy.prototype.__noSuchMethod__ = function*(name, args) {
|
|||
|
||||
let okListener = () => resolve();
|
||||
let valListener = msg => resolve(msg.json.value);
|
||||
let errListener = msg => reject(
|
||||
"error" in msg.objects ? msg.objects.error : msg.json);
|
||||
let errListener = msg => reject(msg.objects.error);
|
||||
|
||||
let handleDialog = function(subject, topic) {
|
||||
listeners.remove();
|
||||
|
@ -2062,7 +2061,7 @@ GeckoDriver.prototype.clickElement = function(cmd, resp) {
|
|||
// listen for it and then just send an error back. The person making the
|
||||
// call should be aware something isnt right and handle accordingly
|
||||
this.addFrameCloseListener("click");
|
||||
yield this.listener.clickElement({id: id});
|
||||
yield this.listener.clickElement(id);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
@ -2086,7 +2085,7 @@ GeckoDriver.prototype.getElementAttribute = function(cmd, resp) {
|
|||
break;
|
||||
|
||||
case Context.CONTENT:
|
||||
resp.value = yield this.listener.getElementAttribute({id: id, name: name});
|
||||
resp.value = yield this.listener.getElementAttribute(id, name);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
@ -2112,7 +2111,7 @@ GeckoDriver.prototype.getElementText = function(cmd, resp) {
|
|||
break;
|
||||
|
||||
case Context.CONTENT:
|
||||
resp.value = yield this.listener.getElementText({id: id});
|
||||
resp.value = yield this.listener.getElementText(id);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
@ -2134,7 +2133,7 @@ GeckoDriver.prototype.getElementTagName = function(cmd, resp) {
|
|||
break;
|
||||
|
||||
case Context.CONTENT:
|
||||
resp.value = yield this.listener.getElementTagName({id: id});
|
||||
resp.value = yield this.listener.getElementTagName(id);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
@ -2224,7 +2223,7 @@ GeckoDriver.prototype.isElementEnabled = function(cmd, resp) {
|
|||
break;
|
||||
|
||||
case Context.CONTENT:
|
||||
resp.value = yield this.listener.isElementEnabled({id: id});
|
||||
resp.value = yield this.listener.isElementEnabled(id);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
@ -2270,7 +2269,7 @@ GeckoDriver.prototype.getElementSize = function(cmd, resp) {
|
|||
break;
|
||||
|
||||
case Context.CONTENT:
|
||||
resp.value = yield this.listener.getElementSize({id: id});
|
||||
resp.value = yield this.listener.getElementSize(id);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
@ -2292,7 +2291,7 @@ GeckoDriver.prototype.getElementRect = function(cmd, resp) {
|
|||
break;
|
||||
|
||||
case Context.CONTENT:
|
||||
resp.value = yield this.listener.getElementRect({id: id});
|
||||
resp.value = yield this.listener.getElementRect(id);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
let {utils: Cu} = Components;
|
||||
|
||||
Cu.import("chrome://marionette/content/error.js");
|
||||
|
||||
/**
|
||||
* The ElementManager manages DOM references and interactions with elements.
|
||||
* According to the WebDriver spec (http://code.google.com/p/selenium/wiki/JsonWireProtocol), the
|
||||
|
@ -28,8 +31,8 @@ this.EXPORTED_SYMBOLS = [
|
|||
|
||||
const DOCUMENT_POSITION_DISCONNECTED = 1;
|
||||
|
||||
let uuidGen = Components.classes["@mozilla.org/uuid-generator;1"]
|
||||
.getService(Components.interfaces.nsIUUIDGenerator);
|
||||
const uuidGen = Components.classes["@mozilla.org/uuid-generator;1"]
|
||||
.getService(Components.interfaces.nsIUUIDGenerator);
|
||||
|
||||
this.CLASS_NAME = "class name";
|
||||
this.SELECTOR = "css selector";
|
||||
|
@ -42,12 +45,6 @@ this.XPATH = "xpath";
|
|||
this.ANON= "anon";
|
||||
this.ANON_ATTRIBUTE = "anon attribute";
|
||||
|
||||
function ElementException(msg, num, stack) {
|
||||
this.message = msg;
|
||||
this.code = num;
|
||||
this.stack = stack;
|
||||
}
|
||||
|
||||
this.Accessibility = function Accessibility() {
|
||||
// A flag indicating whether the accessibility issue should be logged or cause
|
||||
// an exception. Default: log to stdout.
|
||||
|
@ -185,7 +182,7 @@ Accessibility.prototype = {
|
|||
return;
|
||||
}
|
||||
if (this.strict) {
|
||||
throw new ElementException(message, 56, null);
|
||||
throw new ElementNotAccessibleError(message);
|
||||
}
|
||||
dump(Date.now() + " Marionette: " + message);
|
||||
}
|
||||
|
@ -224,19 +221,17 @@ ElementManager.prototype = {
|
|||
let foundEl = null;
|
||||
try {
|
||||
foundEl = this.seenItems[i].get();
|
||||
}
|
||||
catch(e) {}
|
||||
} catch (e) {}
|
||||
if (foundEl) {
|
||||
if (XPCNativeWrapper(foundEl) == XPCNativeWrapper(element)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
else {
|
||||
//cleanup reference to GC'd element
|
||||
} else {
|
||||
// cleanup reference to GC'd element
|
||||
delete this.seenItems[i];
|
||||
}
|
||||
}
|
||||
var id = uuidGen.generateUUID().toString();
|
||||
let id = uuidGen.generateUUID().toString();
|
||||
this.seenItems[id] = Components.utils.getWeakReference(element);
|
||||
return id;
|
||||
},
|
||||
|
@ -255,7 +250,7 @@ ElementManager.prototype = {
|
|||
getKnownElement: function EM_getKnownElement(id, win) {
|
||||
let el = this.seenItems[id];
|
||||
if (!el) {
|
||||
throw new ElementException("Element has not been seen before. Id given was " + id, 17, null);
|
||||
throw new JavaScriptError("Element has not been seen before. Id given was " + id);
|
||||
}
|
||||
try {
|
||||
el = el.get();
|
||||
|
@ -270,8 +265,9 @@ ElementManager.prototype = {
|
|||
!(XPCNativeWrapper(el).ownerDocument == wrappedWin.document) ||
|
||||
(XPCNativeWrapper(el).compareDocumentPosition(wrappedWin.document.documentElement) &
|
||||
DOCUMENT_POSITION_DISCONNECTED)) {
|
||||
throw new ElementException("The element reference is stale. Either the element " +
|
||||
"is no longer attached to the DOM or the page has been refreshed.", 10, null);
|
||||
throw new StaleElementReferenceError(
|
||||
"The element reference is stale. Either the element " +
|
||||
"is no longer attached to the DOM or the page has been refreshed.");
|
||||
}
|
||||
return el;
|
||||
},
|
||||
|
@ -369,8 +365,9 @@ ElementManager.prototype = {
|
|||
args.hasOwnProperty(this.w3cElementKey))) {
|
||||
let elementUniqueIdentifier = args[this.w3cElementKey] ? args[this.w3cElementKey] : args[this.elementKey];
|
||||
converted = this.getKnownElement(elementUniqueIdentifier, win);
|
||||
if (converted == null)
|
||||
throw new ElementException("Unknown element: " + elementUniqueIdentifier, 500, null);
|
||||
if (converted == null) {
|
||||
throw new WebDriverError(`Unknown element: ${elementUniqueIdentifier}`);
|
||||
}
|
||||
}
|
||||
else {
|
||||
converted = {};
|
||||
|
@ -443,7 +440,7 @@ ElementManager.prototype = {
|
|||
let startNode = (values.element != undefined) ?
|
||||
this.getKnownElement(values.element, win) : win.document;
|
||||
if (this.elementStrategies.indexOf(values.using) < 0) {
|
||||
throw new ElementException("No such strategy.", 32, null);
|
||||
throw new InvalidSelectorError(`No such strategy: ${values.using}`);
|
||||
}
|
||||
let found = all ? this.findElements(values.using, values.value, win.document, startNode) :
|
||||
this.findElement(values.using, values.value, win.document, startNode);
|
||||
|
@ -461,7 +458,7 @@ ElementManager.prototype = {
|
|||
} else if (values.using == ANON_ATTRIBUTE) {
|
||||
message = "Unable to locate anonymous element: " + JSON.stringify(values.value);
|
||||
}
|
||||
on_error({message: message, code: 7}, command_id);
|
||||
on_error(new NoSuchElementError(message), command_id);
|
||||
}
|
||||
} else {
|
||||
values.time = startTime;
|
||||
|
@ -594,7 +591,7 @@ ElementManager.prototype = {
|
|||
element = rootNode.getAnonymousElementByAttribute(startNode, attr, value[attr]);
|
||||
break;
|
||||
default:
|
||||
throw new ElementException("No such strategy", 500, null);
|
||||
throw new WebDriverError("No such strategy");
|
||||
}
|
||||
return element;
|
||||
},
|
||||
|
@ -661,7 +658,7 @@ ElementManager.prototype = {
|
|||
}
|
||||
break;
|
||||
default:
|
||||
throw new ElementException("No such strategy", 500, null);
|
||||
throw new WebDriverError("No such strategy");
|
||||
}
|
||||
return elements;
|
||||
},
|
||||
|
|
|
@ -7,11 +7,13 @@
|
|||
const {utils: Cu} = Components;
|
||||
|
||||
const errors = [
|
||||
"ElementNotAccessibleError",
|
||||
"ElementNotVisibleError",
|
||||
"FrameSendFailureError",
|
||||
"FrameSendNotInitializedError",
|
||||
"IllegalArgumentError",
|
||||
"InvalidElementStateError",
|
||||
"InvalidSelectorError",
|
||||
"JavaScriptError",
|
||||
"NoAlertOpenError",
|
||||
"NoSuchElementError",
|
||||
|
@ -19,6 +21,7 @@ const errors = [
|
|||
"NoSuchWindowError",
|
||||
"ScriptTimeoutError",
|
||||
"SessionNotCreatedError",
|
||||
"StaleElementReferenceError",
|
||||
"TimeoutError",
|
||||
"UnknownCommandError",
|
||||
"UnknownError",
|
||||
|
@ -38,11 +41,6 @@ error.toJSON = function(err) {
|
|||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets WebDriver error by its Selenium status code number.
|
||||
*/
|
||||
error.byCode = n => lookup.get(n);
|
||||
|
||||
/**
|
||||
* Determines if the given status code is successful.
|
||||
*/
|
||||
|
@ -130,6 +128,14 @@ this.WebDriverError = function(msg) {
|
|||
};
|
||||
WebDriverError.prototype = Object.create(Error.prototype);
|
||||
|
||||
this.ElementNotAccessibleError = function(msg) {
|
||||
WebDriverError.call(this, msg);
|
||||
this.name = "ElementNotAccessibleError";
|
||||
this.status = "element not accessible";
|
||||
this.code = 56;
|
||||
};
|
||||
ElementNotAccessibleError.prototype = Object.create(WebDriverError.prototype);
|
||||
|
||||
this.ElementNotVisibleError = function(msg) {
|
||||
WebDriverError.call(this, msg);
|
||||
this.name = "ElementNotVisibleError";
|
||||
|
@ -176,6 +182,14 @@ this.InvalidElementStateError = function(msg) {
|
|||
};
|
||||
InvalidElementStateError.prototype = Object.create(WebDriverError.prototype);
|
||||
|
||||
this.InvalidSelectorError = function(msg) {
|
||||
WebDriverError.call(this, msg);
|
||||
this.name = "InvalidSelectorError";
|
||||
this.status = "invalid selector";
|
||||
this.code = 32;
|
||||
};
|
||||
InvalidSelectorError.prototype = Object.create(WebDriverError.prototype);
|
||||
|
||||
/**
|
||||
* Creates an error message for a JavaScript error thrown during
|
||||
* executeScript or executeAsyncScript.
|
||||
|
@ -270,9 +284,17 @@ this.SessionNotCreatedError = function(msg) {
|
|||
this.status = "session not created";
|
||||
// should be 33 to match Selenium
|
||||
this.code = 71;
|
||||
}
|
||||
};
|
||||
SessionNotCreatedError.prototype = Object.create(WebDriverError.prototype);
|
||||
|
||||
this.StaleElementReferenceError = function(msg) {
|
||||
WebDriverError.call(this, msg);
|
||||
this.name = "StaleElementReferenceError";
|
||||
this.status = "stale element reference";
|
||||
this.code = 10;
|
||||
};
|
||||
StaleElementReferenceError.prototype = Object.create(WebDriverError.prototype);
|
||||
|
||||
this.TimeoutError = function(msg) {
|
||||
WebDriverError.call(this, msg);
|
||||
this.name = "TimeoutError";
|
||||
|
@ -304,24 +326,3 @@ this.UnsupportedOperationError = function(msg) {
|
|||
this.code = 405;
|
||||
};
|
||||
UnsupportedOperationError.prototype = Object.create(WebDriverError.prototype);
|
||||
|
||||
const errorObjs = [
|
||||
this.ElementNotVisibleError,
|
||||
this.FrameSendFailureError,
|
||||
this.FrameSendNotInitializedError,
|
||||
this.IllegalArgumentError,
|
||||
this.InvalidElementStateError,
|
||||
this.JavaScriptError,
|
||||
this.NoAlertOpenError,
|
||||
this.NoSuchElementError,
|
||||
this.NoSuchFrameError,
|
||||
this.NoSuchWindowError,
|
||||
this.ScriptTimeoutError,
|
||||
this.SessionNotCreatedError,
|
||||
this.TimeoutError,
|
||||
this.UnknownCommandError,
|
||||
this.UnknownError,
|
||||
this.UnsupportedOperationError,
|
||||
this.WebDriverError,
|
||||
];
|
||||
const lookup = new Map(errorObjs.map(err => [new err().code, err]));
|
||||
|
|
|
@ -15,6 +15,7 @@ loader.loadSubScript("chrome://marionette/content/simpletest.js");
|
|||
loader.loadSubScript("chrome://marionette/content/common.js");
|
||||
loader.loadSubScript("chrome://marionette/content/actions.js");
|
||||
Cu.import("chrome://marionette/content/elements.js");
|
||||
Cu.import("chrome://marionette/content/error.js");
|
||||
Cu.import("resource://gre/modules/FileUtils.jsm");
|
||||
Cu.import("resource://gre/modules/NetUtil.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
@ -93,7 +94,7 @@ let modalHandler = function() {
|
|||
* If the actor returns an ID, we start the listeners. Otherwise, nothing happens.
|
||||
*/
|
||||
function registerSelf() {
|
||||
let msg = {value: winUtil.outerWindowID}
|
||||
let msg = {value: winUtil.outerWindowID};
|
||||
// register will have the ID and a boolean describing if this is the main process or not
|
||||
let register = sendSyncMessage("Marionette:register", msg);
|
||||
|
||||
|
@ -146,6 +147,28 @@ function emitTouchEventForIFrame(message) {
|
|||
message.force, 90);
|
||||
}
|
||||
|
||||
function dispatch(fn) {
|
||||
return function(msg) {
|
||||
let id = msg.json.command_id;
|
||||
try {
|
||||
let rv;
|
||||
if (typeof msg.json == "undefined" || msg.json instanceof Array) {
|
||||
rv = fn.apply(null, msg.json);
|
||||
} else {
|
||||
rv = fn(msg.json);
|
||||
}
|
||||
|
||||
if (typeof rv == "undefined") {
|
||||
sendOk(id);
|
||||
} else {
|
||||
sendResponse({value: rv}, id);
|
||||
}
|
||||
} catch (e) {
|
||||
sendError(e, id);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a message listener that's tied to our listenerId.
|
||||
*/
|
||||
|
@ -160,6 +183,15 @@ function removeMessageListenerId(messageName, handler) {
|
|||
removeMessageListener(messageName + listenerId, handler);
|
||||
}
|
||||
|
||||
let getElementSizeFn = dispatch(getElementSize);
|
||||
let getActiveElementFn = dispatch(getActiveElement);
|
||||
let clickElementFn = dispatch(clickElement);
|
||||
let getElementAttributeFn = dispatch(getElementAttribute);
|
||||
let getElementTextFn = dispatch(getElementText);
|
||||
let getElementTagNameFn = dispatch(getElementTagName);
|
||||
let getElementRectFn = dispatch(getElementRect);
|
||||
let isElementEnabledFn = dispatch(isElementEnabled);
|
||||
|
||||
/**
|
||||
* Start all message listeners
|
||||
*/
|
||||
|
@ -182,17 +214,17 @@ function startListeners() {
|
|||
addMessageListenerId("Marionette:refresh", refresh);
|
||||
addMessageListenerId("Marionette:findElementContent", findElementContent);
|
||||
addMessageListenerId("Marionette:findElementsContent", findElementsContent);
|
||||
addMessageListenerId("Marionette:getActiveElement", getActiveElement);
|
||||
addMessageListenerId("Marionette:clickElement", clickElement);
|
||||
addMessageListenerId("Marionette:getElementAttribute", getElementAttribute);
|
||||
addMessageListenerId("Marionette:getElementText", getElementText);
|
||||
addMessageListenerId("Marionette:getElementTagName", getElementTagName);
|
||||
addMessageListenerId("Marionette:getActiveElement", getActiveElementFn);
|
||||
addMessageListenerId("Marionette:clickElement", clickElementFn);
|
||||
addMessageListenerId("Marionette:getElementAttribute", getElementAttributeFn);
|
||||
addMessageListenerId("Marionette:getElementText", getElementTextFn);
|
||||
addMessageListenerId("Marionette:getElementTagName", getElementTagNameFn);
|
||||
addMessageListenerId("Marionette:isElementDisplayed", isElementDisplayed);
|
||||
addMessageListenerId("Marionette:getElementValueOfCssProperty", getElementValueOfCssProperty);
|
||||
addMessageListenerId("Marionette:submitElement", submitElement);
|
||||
addMessageListenerId("Marionette:getElementSize", getElementSize);
|
||||
addMessageListenerId("Marionette:getElementRect", getElementRect);
|
||||
addMessageListenerId("Marionette:isElementEnabled", isElementEnabled);
|
||||
addMessageListenerId("Marionette:getElementSize", getElementSizeFn); // deprecated
|
||||
addMessageListenerId("Marionette:getElementRect", getElementRectFn);
|
||||
addMessageListenerId("Marionette:isElementEnabled", isElementEnabledFn);
|
||||
addMessageListenerId("Marionette:isElementSelected", isElementSelected);
|
||||
addMessageListenerId("Marionette:sendKeysToElement", sendKeysToElement);
|
||||
addMessageListenerId("Marionette:getElementLocation", getElementLocation); //deprecated
|
||||
|
@ -287,17 +319,17 @@ function deleteSession(msg) {
|
|||
removeMessageListenerId("Marionette:refresh", refresh);
|
||||
removeMessageListenerId("Marionette:findElementContent", findElementContent);
|
||||
removeMessageListenerId("Marionette:findElementsContent", findElementsContent);
|
||||
removeMessageListenerId("Marionette:getActiveElement", getActiveElement);
|
||||
removeMessageListenerId("Marionette:clickElement", clickElement);
|
||||
removeMessageListenerId("Marionette:getElementAttribute", getElementAttribute);
|
||||
removeMessageListenerId("Marionette:getElementText", getElementText);
|
||||
removeMessageListenerId("Marionette:getElementTagName", getElementTagName);
|
||||
removeMessageListenerId("Marionette:getActiveElement", getActiveElementFn);
|
||||
removeMessageListenerId("Marionette:clickElement", clickElementFn);
|
||||
removeMessageListenerId("Marionette:getElementAttribute", getElementAttributeFn);
|
||||
removeMessageListenerId("Marionette:getElementText", getElementTextFn);
|
||||
removeMessageListenerId("Marionette:getElementTagName", getElementTagNameFn);
|
||||
removeMessageListenerId("Marionette:isElementDisplayed", isElementDisplayed);
|
||||
removeMessageListenerId("Marionette:getElementValueOfCssProperty", getElementValueOfCssProperty);
|
||||
removeMessageListenerId("Marionette:submitElement", submitElement);
|
||||
removeMessageListenerId("Marionette:getElementSize", getElementSize); //deprecated
|
||||
removeMessageListenerId("Marionette:getElementRect", getElementRect);
|
||||
removeMessageListenerId("Marionette:isElementEnabled", isElementEnabled);
|
||||
removeMessageListenerId("Marionette:getElementSize", getElementSizeFn); // deprecated
|
||||
removeMessageListenerId("Marionette:getElementRect", getElementRectFn);
|
||||
removeMessageListenerId("Marionette:isElementEnabled", isElementEnabledFn);
|
||||
removeMessageListenerId("Marionette:isElementSelected", isElementSelected);
|
||||
removeMessageListenerId("Marionette:sendKeysToElement", sendKeysToElement);
|
||||
removeMessageListenerId("Marionette:getElementLocation", getElementLocation);
|
||||
|
@ -331,40 +363,42 @@ function deleteSession(msg) {
|
|||
/**
|
||||
* Generic method to send a message to the server
|
||||
*/
|
||||
function sendToServer(msg, value, command_id) {
|
||||
if (command_id) {
|
||||
value.command_id = command_id;
|
||||
function sendToServer(name, data, objs, id) {
|
||||
if (!data) {
|
||||
data = {}
|
||||
}
|
||||
sendAsyncMessage(msg, value);
|
||||
if (id) {
|
||||
data.command_id = id;
|
||||
}
|
||||
sendAsyncMessage(name, data, objs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send response back to server
|
||||
*/
|
||||
function sendResponse(value, command_id) {
|
||||
sendToServer("Marionette:done", value, command_id);
|
||||
sendToServer("Marionette:done", value, null, command_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send ack back to server
|
||||
*/
|
||||
function sendOk(command_id) {
|
||||
sendToServer("Marionette:ok", {}, command_id);
|
||||
sendToServer("Marionette:ok", null, null, command_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send log message to server
|
||||
*/
|
||||
function sendLog(msg) {
|
||||
sendToServer("Marionette:log", { message: msg });
|
||||
sendToServer("Marionette:log", {message: msg});
|
||||
}
|
||||
|
||||
/**
|
||||
* Send error message to server
|
||||
*/
|
||||
function sendError(msg, code, stack, cmdId) {
|
||||
let payload = {message: msg, code: code, stack: stack};
|
||||
sendToServer("Marionette:error", payload, cmdId);
|
||||
function sendError(err, cmdId) {
|
||||
sendToServer("Marionette:error", null, {error: err}, cmdId);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -458,8 +492,8 @@ function createExecuteContentSandbox(aWindow, timeout) {
|
|||
});
|
||||
}
|
||||
|
||||
sandbox.asyncComplete = function sandbox_asyncComplete(value, status, stack, commandId) {
|
||||
if (commandId == asyncTestCommandId) {
|
||||
sandbox.asyncComplete = function(obj, id) {
|
||||
if (id == asyncTestCommandId) {
|
||||
curFrame.removeEventListener("unload", onunload, false);
|
||||
curFrame.clearTimeout(asyncTestTimeoutId);
|
||||
|
||||
|
@ -467,24 +501,19 @@ function createExecuteContentSandbox(aWindow, timeout) {
|
|||
curFrame.clearTimeout(inactivityTimeoutId);
|
||||
}
|
||||
|
||||
|
||||
sendSyncMessage("Marionette:shareData",
|
||||
{log: elementManager.wrapValue(marionetteLogObj.getLogs())});
|
||||
{log: elementManager.wrapValue(marionetteLogObj.getLogs())});
|
||||
marionetteLogObj.clearLogs();
|
||||
|
||||
if (status == 0){
|
||||
if (error.isError(obj)) {
|
||||
sendError(obj, id);
|
||||
} else {
|
||||
if (Object.keys(_emu_cbs).length) {
|
||||
_emu_cbs = {};
|
||||
sendError("Emulator callback still pending when finish() called",
|
||||
500, null, commandId);
|
||||
sendError({message: "Emulator callback still pending when finish() called"}, id);
|
||||
} else {
|
||||
sendResponse({value: elementManager.wrapValue(obj)}, id);
|
||||
}
|
||||
else {
|
||||
sendResponse({value: elementManager.wrapValue(value), status: status},
|
||||
commandId);
|
||||
}
|
||||
}
|
||||
else {
|
||||
sendError(value, status, stack, commandId);
|
||||
}
|
||||
|
||||
asyncTestRunning = false;
|
||||
|
@ -495,33 +524,32 @@ function createExecuteContentSandbox(aWindow, timeout) {
|
|||
};
|
||||
sandbox.finish = function sandbox_finish() {
|
||||
if (asyncTestRunning) {
|
||||
sandbox.asyncComplete(marionette.generate_results(), 0, null, sandbox.asyncTestCommandId);
|
||||
sandbox.asyncComplete(marionette.generate_results(), sandbox.asyncTestCommandId);
|
||||
} else {
|
||||
return marionette.generate_results();
|
||||
}
|
||||
};
|
||||
sandbox.marionetteScriptFinished = function sandbox_marionetteScriptFinished(value) {
|
||||
return sandbox.asyncComplete(value, 0, null, sandbox.asyncTestCommandId);
|
||||
};
|
||||
sandbox.marionetteScriptFinished = val =>
|
||||
sandbox.asyncComplete(val, sandbox.asyncTestCommandId);
|
||||
|
||||
return sandbox;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the given script either as a function body (executeScript)
|
||||
* or directly (for 'mochitest' like JS Marionette tests)
|
||||
* or directly (for mochitest like JS Marionette tests).
|
||||
*/
|
||||
function executeScript(msg, directInject) {
|
||||
// Set up inactivity timeout.
|
||||
if (msg.json.inactivityTimeout) {
|
||||
let setTimer = function() {
|
||||
inactivityTimeoutId = curFrame.setTimeout(function() {
|
||||
sendError('timed out due to inactivity', 28, null, asyncTestCommandId);
|
||||
inactivityTimeoutId = curFrame.setTimeout(function() {
|
||||
sendError(new ScriptTimeoutError("timed out due to inactivity"), asyncTestCommandId);
|
||||
}, msg.json.inactivityTimeout);
|
||||
};
|
||||
|
||||
setTimer();
|
||||
heartbeatCallback = function resetInactivityTimeout() {
|
||||
heartbeatCallback = function() {
|
||||
curFrame.clearTimeout(inactivityTimeoutId);
|
||||
setTimer();
|
||||
};
|
||||
|
@ -534,11 +562,10 @@ function executeScript(msg, directInject) {
|
|||
sandbox = createExecuteContentSandbox(curFrame,
|
||||
msg.json.timeout);
|
||||
if (!sandbox) {
|
||||
sendError("Could not create sandbox!", 500, null, asyncTestCommandId);
|
||||
sendError(new WebDriverError("Could not create sandbox!"), asyncTestCommandId);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
sandbox.asyncTestCommandId = asyncTestCommandId;
|
||||
}
|
||||
|
||||
|
@ -558,7 +585,7 @@ function executeScript(msg, directInject) {
|
|||
marionetteLogObj.clearLogs();
|
||||
|
||||
if (res == undefined || res.passed == undefined) {
|
||||
sendError("Marionette.finish() not called", 17, null, asyncTestCommandId);
|
||||
sendError(new JavaScriptError("Marionette.finish() not called"), asyncTestCommandId);
|
||||
}
|
||||
else {
|
||||
sendResponse({value: elementManager.wrapValue(res)}, asyncTestCommandId);
|
||||
|
@ -568,9 +595,8 @@ function executeScript(msg, directInject) {
|
|||
try {
|
||||
sandbox.__marionetteParams = Cu.cloneInto(elementManager.convertWrappedArguments(
|
||||
msg.json.args, curFrame), sandbox, { wrapReflectors: true });
|
||||
}
|
||||
catch(e) {
|
||||
sendError(e.message, e.code, e.stack, asyncTestCommandId);
|
||||
} catch (e) {
|
||||
sendError(e, asyncTestCommandId);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -590,15 +616,14 @@ function executeScript(msg, directInject) {
|
|||
marionetteLogObj.clearLogs();
|
||||
sendResponse({value: elementManager.wrapValue(res)}, asyncTestCommandId);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
// 17 = JavascriptException
|
||||
let error = createStackMessage(e,
|
||||
"execute_script",
|
||||
msg.json.filename,
|
||||
msg.json.line,
|
||||
script);
|
||||
sendError(error[0], 17, error[1], asyncTestCommandId);
|
||||
} catch (e) {
|
||||
let err = new JavaScriptError(
|
||||
e,
|
||||
"execute_script",
|
||||
msg.json.filename,
|
||||
msg.json.line,
|
||||
script);
|
||||
sendError(err, asyncTestCommandId);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -642,12 +667,12 @@ function executeWithCallback(msg, useFinish) {
|
|||
if (msg.json.inactivityTimeout) {
|
||||
let setTimer = function() {
|
||||
inactivityTimeoutId = curFrame.setTimeout(function() {
|
||||
sandbox.asyncComplete('timed out due to inactivity', 28, null, asyncTestCommandId);
|
||||
sandbox.asyncComplete(new ScriptTimeout("timed out due to inactivity"), asyncTestCommandId);
|
||||
}, msg.json.inactivityTimeout);
|
||||
};
|
||||
|
||||
setTimer();
|
||||
heartbeatCallback = function resetInactivityTimeout() {
|
||||
heartbeatCallback = function() {
|
||||
curFrame.clearTimeout(inactivityTimeoutId);
|
||||
setTimer();
|
||||
};
|
||||
|
@ -657,7 +682,7 @@ function executeWithCallback(msg, useFinish) {
|
|||
asyncTestCommandId = msg.json.command_id;
|
||||
|
||||
onunload = function() {
|
||||
sendError("unload was called", 17, null, asyncTestCommandId);
|
||||
sendError(new JavaScriptError("unload was called"), asyncTestCommandId);
|
||||
};
|
||||
curFrame.addEventListener("unload", onunload, false);
|
||||
|
||||
|
@ -665,7 +690,7 @@ function executeWithCallback(msg, useFinish) {
|
|||
sandbox = createExecuteContentSandbox(curFrame,
|
||||
msg.json.timeout);
|
||||
if (!sandbox) {
|
||||
sendError("Could not create sandbox!", 17, null, asyncTestCommandId);
|
||||
sendError(new JavaScriptError("Could not create sandbox!"), asyncTestCommandId);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -680,19 +705,19 @@ function executeWithCallback(msg, useFinish) {
|
|||
// http://code.google.com/p/selenium/source/browse/trunk/javascript/firefox-driver/js/evaluate.js.
|
||||
// We'll stay compatible with the Selenium code.
|
||||
asyncTestTimeoutId = curFrame.setTimeout(function() {
|
||||
sandbox.asyncComplete('timed out', 28, null, asyncTestCommandId);
|
||||
sandbox.asyncComplete(new ScriptTimeoutError("timed out"), asyncTestCommandId);
|
||||
}, msg.json.timeout);
|
||||
|
||||
originalOnError = curFrame.onerror;
|
||||
curFrame.onerror = function errHandler(errMsg, url, line) {
|
||||
sandbox.asyncComplete(errMsg, 17, "@" + url + ", line " + line, asyncTestCommandId);
|
||||
curFrame.onerror = function errHandler(msg, url, line) {
|
||||
sandbox.asyncComplete(new JavaScriptError(msg + "@" + url + ", line " + line), asyncTestCommandId);
|
||||
curFrame.onerror = originalOnError;
|
||||
};
|
||||
|
||||
let scriptSrc;
|
||||
if (useFinish) {
|
||||
if (msg.json.timeout == null || msg.json.timeout == 0) {
|
||||
sendError("Please set a timeout", 21, null, asyncTestCommandId);
|
||||
sendError(new TimeoutError("Please set a timeout"), asyncTestCommandId);
|
||||
}
|
||||
scriptSrc = script;
|
||||
}
|
||||
|
@ -700,9 +725,8 @@ function executeWithCallback(msg, useFinish) {
|
|||
try {
|
||||
sandbox.__marionetteParams = Cu.cloneInto(elementManager.convertWrappedArguments(
|
||||
msg.json.args, curFrame), sandbox, { wrapReflectors: true });
|
||||
}
|
||||
catch(e) {
|
||||
sendError(e.message, e.code, e.stack, asyncTestCommandId);
|
||||
} catch (e) {
|
||||
sendError(e, asyncTestCommandId);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -723,13 +747,13 @@ function executeWithCallback(msg, useFinish) {
|
|||
}
|
||||
Cu.evalInSandbox(scriptSrc, sandbox, "1.8", "dummy file", 0);
|
||||
} catch (e) {
|
||||
// 17 = JavascriptException
|
||||
let error = createStackMessage(e,
|
||||
"execute_async_script",
|
||||
msg.json.filename,
|
||||
msg.json.line,
|
||||
scriptSrc);
|
||||
sandbox.asyncComplete(error[0], 17, error[1], asyncTestCommandId);
|
||||
let err = new JavaScriptError(
|
||||
e,
|
||||
"execute_async_script",
|
||||
msg.json.filename,
|
||||
msg.json.line,
|
||||
scriptSrc);
|
||||
sandbox.asyncComplete(err, asyncTestCommandId);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -856,7 +880,7 @@ function singleTap(msg) {
|
|||
let visible = checkVisible(el, msg.json.corx, msg.json.cory);
|
||||
checkVisibleAccessibility(acc, visible);
|
||||
if (!visible) {
|
||||
sendError("Element is not currently visible and may not be manipulated", 11, null, command_id);
|
||||
sendError(new ElementNotVisibleError("Element is not currently visible and may not be manipulated"), command_id);
|
||||
return;
|
||||
}
|
||||
checkActionableAccessibility(acc);
|
||||
|
@ -871,10 +895,9 @@ function singleTap(msg) {
|
|||
emitTouchEvent('touchend', touch);
|
||||
}
|
||||
actions.mouseTap(el.ownerDocument, c.x, c.y);
|
||||
sendOk(msg.json.command_id);
|
||||
}
|
||||
catch (e) {
|
||||
sendError(e.message, e.code, e.stack, msg.json.command_id);
|
||||
sendOk(command_id);
|
||||
} catch (e) {
|
||||
sendError(e, command_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -959,12 +982,8 @@ function actionChain(msg) {
|
|||
let touchId = msg.json.nextId;
|
||||
|
||||
let callbacks = {};
|
||||
callbacks.onSuccess = (value) => {
|
||||
sendResponse(value, command_id);
|
||||
};
|
||||
callbacks.onError = (message, code, trace) => {
|
||||
sendError(message, code, trace, msg.json.command_id);
|
||||
};
|
||||
callbacks.onSuccess = value => sendResponse(value, command_id);
|
||||
callbacks.onError = err => sendError(err, command_id);
|
||||
|
||||
let touchProvider = {};
|
||||
touchProvider.createATouch = createATouch;
|
||||
|
@ -979,7 +998,7 @@ function actionChain(msg) {
|
|||
callbacks,
|
||||
touchProvider);
|
||||
} catch (e) {
|
||||
sendError(e.message, e.code, e.stack, command_id);
|
||||
sendError(e, command_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1144,9 +1163,8 @@ function multiAction(msg) {
|
|||
// pendingTouches keeps track of current touches that's on the screen
|
||||
let pendingTouches = [];
|
||||
setDispatch(concurrentEvent, pendingTouches, command_id);
|
||||
}
|
||||
catch (e) {
|
||||
sendError(e.message, e.code, e.stack, msg.json.command_id);
|
||||
} catch (e) {
|
||||
sendError(e, command_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1178,7 +1196,7 @@ function pollForReadyState(msg, start, callback) {
|
|||
!curFrame.document.baseURI.startsWith(url)) {
|
||||
// We have reached an error url without requesting it.
|
||||
callback();
|
||||
sendError("Error loading page", 13, null, command_id);
|
||||
sendError(new UnknownError("Error loading page"), command_id);
|
||||
} else if (curFrame.document.readyState == "interactive" &&
|
||||
curFrame.document.baseURI.startsWith("about:")) {
|
||||
callback();
|
||||
|
@ -1186,11 +1204,9 @@ function pollForReadyState(msg, start, callback) {
|
|||
} else {
|
||||
navTimer.initWithCallback(checkLoad, 100, Ci.nsITimer.TYPE_ONE_SHOT);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
callback();
|
||||
sendError("Error loading page, timed out (checkLoad)", 21, null,
|
||||
command_id);
|
||||
sendError(new TimeoutError("Error loading page, timed out (checkLoad)"), command_id);
|
||||
}
|
||||
}
|
||||
checkLoad();
|
||||
|
@ -1220,8 +1236,7 @@ function get(msg) {
|
|||
|
||||
function timerFunc() {
|
||||
removeEventListener("DOMContentLoaded", onDOMContentLoaded, false);
|
||||
sendError("Error loading page, timed out (onDOMContentLoaded)", 21,
|
||||
null, msg.json.command_id);
|
||||
sendError(new TimeoutError("Error loading page, timed out (onDOMContentLoaded)"), msg.json.command_id);
|
||||
}
|
||||
if (msg.json.pageTimeout != null) {
|
||||
navTimer.initWithCallback(timerFunc, msg.json.pageTimeout, Ci.nsITimer.TYPE_ONE_SHOT);
|
||||
|
@ -1306,13 +1321,12 @@ function refresh(msg) {
|
|||
function findElementContent(msg) {
|
||||
let command_id = msg.json.command_id;
|
||||
try {
|
||||
let on_success = function(el, cmd_id) { sendResponse({value: el}, cmd_id) };
|
||||
let on_error = function(e, cmd_id) { sendError(e.message, e.code, null, cmd_id); };
|
||||
let onSuccess = (el, id) => sendResponse({value: el}, id);
|
||||
let onError = (err, id) => sendError(err, id);
|
||||
elementManager.find(curFrame, msg.json, msg.json.searchTimeout,
|
||||
false /* all */, on_success, on_error, command_id);
|
||||
}
|
||||
catch (e) {
|
||||
sendError(e.message, e.code, e.stack, command_id);
|
||||
false /* all */, onSuccess, onError, command_id);
|
||||
} catch (e) {
|
||||
sendError(e, command_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1322,97 +1336,90 @@ function findElementContent(msg) {
|
|||
function findElementsContent(msg) {
|
||||
let command_id = msg.json.command_id;
|
||||
try {
|
||||
let on_success = function(els, cmd_id) { sendResponse({value: els}, cmd_id); };
|
||||
let on_error = function(e, cmd_id) { sendError(e.message, e.code, null, cmd_id); };
|
||||
let onSuccess = (els, id) => sendResponse({value: els}, id);
|
||||
let onError = (err, id) => sendError(err, id);
|
||||
elementManager.find(curFrame, msg.json, msg.json.searchTimeout,
|
||||
true /* all */, on_success, on_error, command_id);
|
||||
}
|
||||
catch (e) {
|
||||
sendError(e.message, e.code, e.stack, command_id);
|
||||
true /* all */, onSuccess, onError, command_id);
|
||||
} catch (e) {
|
||||
sendError(e, command_id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find and return the active element on the page
|
||||
* Find and return the active element on the page.
|
||||
*
|
||||
* @return {WebElement}
|
||||
* Reference to web element.
|
||||
*/
|
||||
function getActiveElement(msg) {
|
||||
let command_id = msg.json.command_id;
|
||||
var element = curFrame.document.activeElement;
|
||||
var id = elementManager.addToKnownElements(element);
|
||||
sendResponse({value: id}, command_id);
|
||||
function getActiveElement() {
|
||||
let el = curFrame.document.activeElement;
|
||||
return elementManager.addToKnownElements(el);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send click event to element
|
||||
* Send click event to element.
|
||||
*
|
||||
* @param {WebElement} id
|
||||
* Reference to the web element to click.
|
||||
*/
|
||||
function clickElement(msg) {
|
||||
let command_id = msg.json.command_id;
|
||||
let el;
|
||||
try {
|
||||
el = elementManager.getKnownElement(msg.json.id, curFrame);
|
||||
let acc = accessibility.getAccessibleObject(el, true);
|
||||
let visible = checkVisible(el);
|
||||
checkVisibleAccessibility(acc, visible);
|
||||
if (visible) {
|
||||
checkActionableAccessibility(acc);
|
||||
if (utils.isElementEnabled(el)) {
|
||||
utils.synthesizeMouseAtCenter(el, {}, el.ownerDocument.defaultView)
|
||||
}
|
||||
else {
|
||||
sendError("Element is not Enabled", 12, null, command_id)
|
||||
}
|
||||
}
|
||||
else {
|
||||
sendError("Element is not visible", 11, null, command_id)
|
||||
}
|
||||
sendOk(command_id);
|
||||
function clickElement(id) {
|
||||
let el = elementManager.getKnownElement(id, curFrame);
|
||||
let acc = accessibility.getAccessibleObject(el, true);
|
||||
let visible = checkVisible(el);
|
||||
checkVisibleAccessibility(acc, visible);
|
||||
if (!visible) {
|
||||
throw new ElementNotVisibleError("Element is not visible");
|
||||
}
|
||||
catch (e) {
|
||||
sendError(e.message, e.code, e.stack, command_id);
|
||||
checkActionableAccessibility(acc);
|
||||
if (utils.isElementEnabled(el)) {
|
||||
utils.synthesizeMouseAtCenter(el, {}, el.ownerDocument.defaultView);
|
||||
} else {
|
||||
throw new InvalidElementStateError("Element is not Enabled");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a given attribute of an element
|
||||
* Get a given attribute of an element.
|
||||
*
|
||||
* @param {WebElement} id
|
||||
* Reference to the web element to get the attribute of.
|
||||
* @param {string} name
|
||||
* Name of the attribute.
|
||||
*
|
||||
* @return {string}
|
||||
* The value of the attribute.
|
||||
*/
|
||||
function getElementAttribute(msg) {
|
||||
let command_id = msg.json.command_id;
|
||||
try {
|
||||
let el = elementManager.getKnownElement(msg.json.id, curFrame);
|
||||
sendResponse({value: utils.getElementAttribute(el, msg.json.name)},
|
||||
command_id);
|
||||
}
|
||||
catch (e) {
|
||||
sendError(e.message, e.code, e.stack, command_id);
|
||||
}
|
||||
function getElementAttribute(id, name) {
|
||||
let el = elementManager.getKnownElement(id, curFrame);
|
||||
return utils.getElementAttribute(el, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the text of this element. This includes text from child elements.
|
||||
*
|
||||
* @param {WebElement} id
|
||||
* Reference to web element.
|
||||
*
|
||||
* @return {string}
|
||||
* Text of element.
|
||||
*/
|
||||
function getElementText(msg) {
|
||||
let command_id = msg.json.command_id;
|
||||
try {
|
||||
let el = elementManager.getKnownElement(msg.json.id, curFrame);
|
||||
sendResponse({value: utils.getElementText(el)}, command_id);
|
||||
}
|
||||
catch (e) {
|
||||
sendError(e.message, e.code, e.stack, command_id);
|
||||
}
|
||||
function getElementText(id) {
|
||||
let el = elementManager.getKnownElement(id, curFrame);
|
||||
return utils.getElementText(el);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the tag name of an element.
|
||||
*
|
||||
* @param {WebElement} id
|
||||
* Reference to web element.
|
||||
*
|
||||
* @return {string}
|
||||
* Tag name of element.
|
||||
*/
|
||||
function getElementTagName(msg) {
|
||||
let command_id = msg.json.command_id;
|
||||
try {
|
||||
let el = elementManager.getKnownElement(msg.json.id, curFrame);
|
||||
sendResponse({value: el.tagName.toLowerCase()}, command_id);
|
||||
}
|
||||
catch (e) {
|
||||
sendError(e.message, e.code, e.stack, command_id);
|
||||
}
|
||||
function getElementTagName(id) {
|
||||
let el = elementManager.getKnownElement(id, curFrame);
|
||||
return el.tagName.toLowerCase();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1425,9 +1432,8 @@ function isElementDisplayed(msg) {
|
|||
let displayed = utils.isElementDisplayed(el);
|
||||
checkVisibleAccessibility(accessibility.getAccessibleObject(el), displayed);
|
||||
sendResponse({value: displayed}, command_id);
|
||||
}
|
||||
catch (e) {
|
||||
sendError(e.message, e.code, e.stack, command_id);
|
||||
} catch (e) {
|
||||
sendError(e, command_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1446,9 +1452,8 @@ function getElementValueOfCssProperty(msg){
|
|||
let el = elementManager.getKnownElement(msg.json.id, curFrame);
|
||||
sendResponse({value: curFrame.document.defaultView.getComputedStyle(el, null).getPropertyValue(propertyName)},
|
||||
command_id);
|
||||
}
|
||||
catch (e) {
|
||||
sendError(e.message, e.code, e.stack, command_id);
|
||||
} catch (e) {
|
||||
sendError(e, command_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1467,67 +1472,63 @@ function submitElement (msg) {
|
|||
if (el.tagName && el.tagName.toLowerCase() == 'form') {
|
||||
el.submit();
|
||||
sendOk(command_id);
|
||||
} else {
|
||||
sendError(new NoSuchElementError("Element is not a form element or in a form"), command_id);
|
||||
}
|
||||
else {
|
||||
sendError("Element is not a form element or in a form", 7, null, command_id);
|
||||
}
|
||||
|
||||
}
|
||||
catch (e) {
|
||||
sendError(e.message, e.code, e.stack, command_id);
|
||||
} catch (e) {
|
||||
sendError(e, command_id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the size of the element and return it
|
||||
* Get the size of the element.
|
||||
*
|
||||
* @param {WebElement} id
|
||||
* Web element reference.
|
||||
*
|
||||
* @return {Object.<string, number>}
|
||||
* The width/height dimensions of th element.
|
||||
*/
|
||||
function getElementSize(msg){
|
||||
let command_id = msg.json.command_id;
|
||||
try {
|
||||
let el = elementManager.getKnownElement(msg.json.id, curFrame);
|
||||
let clientRect = el.getBoundingClientRect();
|
||||
sendResponse({value: {width: clientRect.width, height: clientRect.height}},
|
||||
command_id);
|
||||
}
|
||||
catch (e) {
|
||||
sendError(e.message, e.code, e.stack, command_id);
|
||||
}
|
||||
function getElementSize(id) {
|
||||
let el = elementManager.getKnownElement(id, curFrame);
|
||||
let clientRect = el.getBoundingClientRect();
|
||||
return {width: clientRect.width, height: clientRect.height};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the size of the element and return it
|
||||
* Get the size of the element.
|
||||
*
|
||||
* @param {WebElement} id
|
||||
* Reference to web element.
|
||||
*
|
||||
* @return {Object.<string, number>}
|
||||
* The x, y, width, and height properties of the element.
|
||||
*/
|
||||
function getElementRect(msg){
|
||||
let command_id = msg.json.command_id;
|
||||
try {
|
||||
let el = elementManager.getKnownElement(msg.json.id, curFrame);
|
||||
let clientRect = el.getBoundingClientRect();
|
||||
sendResponse({value: {x: clientRect.x + curFrame.pageXOffset,
|
||||
y: clientRect.y + curFrame.pageYOffset,
|
||||
width: clientRect.width,
|
||||
height: clientRect.height}},
|
||||
command_id);
|
||||
}
|
||||
catch (e) {
|
||||
sendError(e.message, e.code, e.stack, command_id);
|
||||
}
|
||||
function getElementRect(id) {
|
||||
let el = elementManager.getKnownElement(id, curFrame);
|
||||
let clientRect = el.getBoundingClientRect();
|
||||
return {
|
||||
x: clientRect.x + curFrame.pageXOffset,
|
||||
y: clientRect.y + curFrame.pageYOffset,
|
||||
width: clientRect.width,
|
||||
height: clientRect.height
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if element is enabled
|
||||
* Check if element is enabled.
|
||||
*
|
||||
* @param {WebElement} id
|
||||
* Reference to web element.
|
||||
*
|
||||
* @return {boolean}
|
||||
* True if enabled, false otherwise.
|
||||
*/
|
||||
function isElementEnabled(msg) {
|
||||
let command_id = msg.json.command_id;
|
||||
try {
|
||||
let el = elementManager.getKnownElement(msg.json.id, curFrame);
|
||||
let enabled = utils.isElementEnabled(el);
|
||||
checkEnabledStateAccessibility(accessibility.getAccessibleObject(el),
|
||||
enabled);
|
||||
sendResponse({value: enabled}, command_id);
|
||||
}
|
||||
catch (e) {
|
||||
sendError(e.message, e.code, e.stack, command_id);
|
||||
}
|
||||
function isElementEnabled(id) {
|
||||
let el = elementManager.getKnownElement(id, curFrame);
|
||||
let enabled = utils.isElementEnabled(el);
|
||||
checkEnabledStateAccessibility(accessibility.getAccessibleObject(el), enabled);
|
||||
return enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1538,9 +1539,8 @@ function isElementSelected(msg) {
|
|||
try {
|
||||
let el = elementManager.getKnownElement(msg.json.id, curFrame);
|
||||
sendResponse({value: utils.isElementSelected(el)}, command_id);
|
||||
}
|
||||
catch (e) {
|
||||
sendError(e.message, e.code, e.stack, command_id);
|
||||
} catch (e) {
|
||||
sendError(e, command_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1598,9 +1598,8 @@ function getElementLocation(msg) {
|
|||
location.y = rect.top;
|
||||
|
||||
sendResponse({value: location}, command_id);
|
||||
}
|
||||
catch (e) {
|
||||
sendError(e.message, e.code, e.stack, command_id);
|
||||
} catch (e) {
|
||||
sendError(e, command_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1618,7 +1617,7 @@ function clearElement(msg) {
|
|||
}
|
||||
sendOk(command_id);
|
||||
} catch (e) {
|
||||
sendError(e.message, e.code, e.stack, command_id);
|
||||
sendError(e, command_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1633,9 +1632,9 @@ function switchToFrame(msg) {
|
|||
if (curFrame.document.readyState == "complete") {
|
||||
sendOk(command_id);
|
||||
return;
|
||||
}
|
||||
else if (curFrame.document.readyState == "interactive" && errorRegex.exec(curFrame.document.baseURI)) {
|
||||
sendError("Error loading page", 13, null, command_id);
|
||||
} else if (curFrame.document.readyState == "interactive" &&
|
||||
errorRegex.exec(curFrame.document.baseURI)) {
|
||||
sendError(new UnknownError("Error loading page"), command_id);
|
||||
return;
|
||||
}
|
||||
checkTimer.initWithCallback(checkLoad, 100, Ci.nsITimer.TYPE_ONE_SHOT);
|
||||
|
@ -1675,9 +1674,8 @@ function switchToFrame(msg) {
|
|||
let wantedFrame;
|
||||
try {
|
||||
wantedFrame = elementManager.getKnownElement(msg.json.element, curFrame); //Frame Element
|
||||
}
|
||||
catch(e) {
|
||||
sendError(e.message, e.code, e.stack, command_id);
|
||||
} catch (e) {
|
||||
sendError(e, command_id);
|
||||
}
|
||||
|
||||
if (frames.length > 0) {
|
||||
|
@ -1735,8 +1733,9 @@ function switchToFrame(msg) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (foundFrame === null) {
|
||||
sendError("Unable to locate frame: " + (msg.json.id || msg.json.element), 8, null, command_id);
|
||||
sendError(new NoSuchFrameError("Unable to locate frame: " + (msg.json.id || msg.json.element)), command_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1777,12 +1776,11 @@ function addCookie(msg) {
|
|||
if (!cookie.domain) {
|
||||
var location = curFrame.document.location;
|
||||
cookie.domain = location.hostname;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
var currLocation = curFrame.location;
|
||||
var currDomain = currLocation.host;
|
||||
if (currDomain.indexOf(cookie.domain) == -1) {
|
||||
sendError("You may only set cookies for the current domain", 24, null, msg.json.command_id);
|
||||
sendError(new InvalidCookieDomainError("You may only set cookies for the current domain"), msg.json.command_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1795,12 +1793,12 @@ function addCookie(msg) {
|
|||
|
||||
var document = curFrame.document;
|
||||
if (!document || !document.contentType.match(/html/i)) {
|
||||
sendError('You may only set cookies on html documents', 25, null, msg.json.command_id);
|
||||
sendError(new UnableToSetCookie("You may only set cookies on html documents"), msg.json.command_id);
|
||||
}
|
||||
|
||||
let added = sendSyncMessage("Marionette:addCookie", {value: cookie});
|
||||
if (added[0] !== true) {
|
||||
sendError("Error setting cookie", 13, null, msg.json.command_id);
|
||||
sendError(new UnknownError("Error setting cookie"), msg.json.command_id);
|
||||
return;
|
||||
}
|
||||
sendOk(msg.json.command_id);
|
||||
|
@ -1841,7 +1839,7 @@ function deleteCookie(msg) {
|
|||
if (cookie.name == toDelete) {
|
||||
let deleted = sendSyncMessage("Marionette:deleteCookie", {value: cookie});
|
||||
if (deleted[0] !== true) {
|
||||
sendError("Could not delete cookie: " + msg.json.name, 13, null, msg.json.command_id);
|
||||
sendError(new UnknownError("Could not delete cookie: " + msg.json.name), msg.json.command_id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1858,7 +1856,7 @@ function deleteAllCookies(msg) {
|
|||
for (let cookie of cookies) {
|
||||
let deleted = sendSyncMessage("Marionette:deleteCookie", {value: cookie});
|
||||
if (!deleted[0]) {
|
||||
sendError("Could not delete cookie: " + JSON.stringify(cookie), 13, null, msg.json.command_id);
|
||||
sendError(new UnknownError("Could not delete cookie: " + JSON.stringify(cookie)), msg.json.command_id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1912,9 +1910,8 @@ function emulatorCmdResult(msg) {
|
|||
}
|
||||
try {
|
||||
cb(message.result);
|
||||
}
|
||||
catch(e) {
|
||||
sendError(e.message, e.code, e.stack, -1);
|
||||
} catch (e) {
|
||||
sendError(e, -1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,8 +17,11 @@
|
|||
*/
|
||||
|
||||
let {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
||||
|
||||
Cu.import("chrome://marionette/content/error.js");
|
||||
|
||||
let loader = Cc["@mozilla.org/moz/jssubscript-loader;1"]
|
||||
.getService(Ci.mozIJSSubScriptLoader);
|
||||
.getService(Ci.mozIJSSubScriptLoader);
|
||||
|
||||
let utils = {};
|
||||
loader.loadSubScript("chrome://marionette/content/EventUtils.js", utils);
|
||||
|
@ -138,8 +141,7 @@ function sendKeysToElement (document, element, keysToSend, successCallback, erro
|
|||
sendSingleKey(c, modifiers, document);
|
||||
}
|
||||
successCallback(command_id);
|
||||
}
|
||||
else {
|
||||
errorCallback("Element is not visible", 11, null, command_id);
|
||||
} else {
|
||||
errorCallback(new ElementNotVisibleError("Element is not visible"), command_id);
|
||||
}
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче