зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1336214 - Preserve stacktraces in Marionette errors; r=maja_zf
Since bug 1326534 we have discarded the original stacktrace from errors originating inside Marionette. This was due to faulty logic when attempting to generate a new stacktrace when it was missing from a propagated error. This change simplifies WebDriver errors by making use of Error inheritance. The WebDriver error specific functions error.toJson and error.fromJson has additionally been moved to WebDriverError. MozReview-Commit-ID: C3Ns0H01LyG --HG-- extra : rebase_source : 0c705054dae8c0647500bb90e9b970cc57e712c4
This commit is contained in:
Родитель
d9976f6943
Коммит
69d406c698
|
@ -32,12 +32,12 @@ this.assert = {};
|
|||
* @return {string}
|
||||
* Session ID.
|
||||
*
|
||||
* @throws {InvalidSessionIdError}
|
||||
* @throws {InvalidSessionIDError}
|
||||
* If |driver| does not have a session ID.
|
||||
*/
|
||||
assert.session = function (driver, msg = "") {
|
||||
assert.that(sessionID => sessionID,
|
||||
msg, InvalidSessionIdError)(driver.sessionId);
|
||||
msg, InvalidSessionIDError)(driver.sessionId);
|
||||
return driver.sessionId;
|
||||
};
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ const ERRORS = new Set([
|
|||
"InvalidArgumentError",
|
||||
"InvalidElementStateError",
|
||||
"InvalidSelectorError",
|
||||
"InvalidSessionIdError",
|
||||
"InvalidSessionIDError",
|
||||
"JavaScriptError",
|
||||
"NoAlertOpenError",
|
||||
"NoSuchElementError",
|
||||
|
@ -81,14 +81,15 @@ error.isWebDriverError = function (obj) {
|
|||
};
|
||||
|
||||
/**
|
||||
* Wraps an Error as a WebDriverError type. If the given error is already
|
||||
* in the WebDriverError prototype chain, this function acts as a no-op.
|
||||
* Wraps any error as a WebDriverError. If the given error is already in
|
||||
* the WebDriverError prototype chain, this function returns it
|
||||
* unmodified.
|
||||
*/
|
||||
error.wrap = function (err) {
|
||||
if (error.isWebDriverError(err)) {
|
||||
return err;
|
||||
}
|
||||
return new WebDriverError(`${err.name}: ${err.message}`, err.stacktrace);
|
||||
return new WebDriverError(err);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -96,7 +97,7 @@ error.wrap = function (err) {
|
|||
* and reports error to the Browser Console.
|
||||
*/
|
||||
error.report = function (err) {
|
||||
let msg = `Marionette threw an error: ${error.stringify(err)}`;
|
||||
let msg = "Marionette threw an error: " + error.stringify(err);
|
||||
dump(msg + "\n");
|
||||
if (Cu.reportError) {
|
||||
Cu.reportError(msg);
|
||||
|
@ -144,260 +145,245 @@ error.pprint = function (strings, ...values) {
|
|||
return res.join("");
|
||||
};
|
||||
|
||||
/**
|
||||
* Marshal a WebDriverError prototype to a JSON dictionary.
|
||||
*
|
||||
* @param {WebDriverError} err
|
||||
* Error to serialise.
|
||||
*
|
||||
* @return {Object.<string, Object>}
|
||||
* JSON dictionary with the keys "error", "message", and "stacktrace".
|
||||
* @throws {TypeError}
|
||||
* If error type is not serialisable.
|
||||
*/
|
||||
error.toJson = function (err) {
|
||||
if (!error.isWebDriverError(err)) {
|
||||
throw new TypeError(`Unserialisable error type: ${err}`);
|
||||
}
|
||||
|
||||
let json = {
|
||||
error: err.status,
|
||||
message: err.message || "",
|
||||
stacktrace: err.stack || "",
|
||||
};
|
||||
return json;
|
||||
};
|
||||
|
||||
/**
|
||||
* Unmarshal a JSON dictionary to a WebDriverError prototype.
|
||||
*
|
||||
* @param {Object.<string, string>} json
|
||||
* JSON dictionary with the keys "error", "message", and "stacktrace".
|
||||
*
|
||||
* @return {WebDriverError}
|
||||
* Deserialised error prototype.
|
||||
*/
|
||||
error.fromJson = function (json) {
|
||||
if (!statusLookup.has(json.error)) {
|
||||
throw new TypeError(`Undeserialisable error type: ${json.error}`);
|
||||
}
|
||||
|
||||
let errCls = statusLookup.get(json.error);
|
||||
let err = new errCls(json.message);
|
||||
if ("stacktrace" in json) {
|
||||
err.stack = json.stacktrace;
|
||||
}
|
||||
return err;
|
||||
};
|
||||
|
||||
/**
|
||||
* WebDriverError is the prototypal parent of all WebDriver errors.
|
||||
* It should not be used directly, as it does not correspond to a real
|
||||
* error in the specification.
|
||||
*
|
||||
* @param {(string|Error)=} err
|
||||
* Optional string describing error situation or Error instance
|
||||
* to propagate.
|
||||
*/
|
||||
this.WebDriverError = function (err) {
|
||||
const proto = Error.call(this, err);
|
||||
this.name = "WebDriverError";
|
||||
this.status = "webdriver error";
|
||||
class WebDriverError extends Error {
|
||||
/**
|
||||
* @param {(string|Error)=} x
|
||||
* Optional string describing error situation or Error instance
|
||||
* to propagate.
|
||||
*/
|
||||
constructor (x) {
|
||||
super(x);
|
||||
this.name = this.constructor.name;
|
||||
this.status = "webdriver error";
|
||||
|
||||
if (error.isError(err)) {
|
||||
this.message = err.message;
|
||||
this.stack = err.stack;
|
||||
} else {
|
||||
this.message = err;
|
||||
this.stack = proto.stack;
|
||||
// Error's ctor does not preserve x' stack
|
||||
if (error.isError(x)) {
|
||||
this.stack = x.stack;
|
||||
}
|
||||
}
|
||||
};
|
||||
WebDriverError.prototype = Object.create(Error.prototype);
|
||||
|
||||
this.ElementNotAccessibleError = function (msg) {
|
||||
WebDriverError.call(this, msg);
|
||||
this.name = "ElementNotAccessibleError";
|
||||
this.status = "element not accessible";
|
||||
};
|
||||
ElementNotAccessibleError.prototype = Object.create(WebDriverError.prototype);
|
||||
toJSON () {
|
||||
return {
|
||||
error: this.status,
|
||||
message: this.message || "",
|
||||
stacktrace: this.stack || "",
|
||||
}
|
||||
}
|
||||
|
||||
this.ElementNotVisibleError = function (msg) {
|
||||
WebDriverError.call(this, msg);
|
||||
this.name = "ElementNotVisibleError";
|
||||
this.status = "element not visible";
|
||||
};
|
||||
ElementNotVisibleError.prototype = Object.create(WebDriverError.prototype);
|
||||
static fromJSON (json) {
|
||||
if (typeof json.error == "undefined") {
|
||||
let s = JSON.stringify(json);
|
||||
throw new TypeError("Undeserialisable error type: " + s);
|
||||
}
|
||||
if (!STATUSES.has(json.error)) {
|
||||
throw new TypeError("Not of WebDriverError descent: " + json.error);
|
||||
}
|
||||
|
||||
this.InsecureCertificateError = function (msg) {
|
||||
WebDriverError.call(this, msg);
|
||||
this.name = "InsecureCertificateError";
|
||||
this.status = "insecure certificate";
|
||||
};
|
||||
InsecureCertificateError.prototype = Object.create(WebDriverError.prototype);
|
||||
let cls = STATUSES.get(json.error);
|
||||
let err = new cls();
|
||||
if ("message" in json) {
|
||||
err.message = json.message;
|
||||
}
|
||||
if ("stacktrace" in json) {
|
||||
err.stack = json.stacktrace;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
this.InvalidArgumentError = function (msg) {
|
||||
WebDriverError.call(this, msg);
|
||||
this.name = "InvalidArgumentError";
|
||||
this.status = "invalid argument";
|
||||
};
|
||||
InvalidArgumentError.prototype = Object.create(WebDriverError.prototype);
|
||||
class ElementNotAccessibleError extends WebDriverError {
|
||||
constructor (message) {
|
||||
super(message);
|
||||
this.status = "element not accessible";
|
||||
}
|
||||
}
|
||||
|
||||
this.InvalidElementStateError = function (msg) {
|
||||
WebDriverError.call(this, msg);
|
||||
this.name = "InvalidElementStateError";
|
||||
this.status = "invalid element state";
|
||||
};
|
||||
InvalidElementStateError.prototype = Object.create(WebDriverError.prototype);
|
||||
class ElementNotVisibleError extends WebDriverError {
|
||||
constructor (message) {
|
||||
super(message);
|
||||
this.status = "element not visible";
|
||||
}
|
||||
}
|
||||
|
||||
this.InvalidSelectorError = function (msg) {
|
||||
WebDriverError.call(this, msg);
|
||||
this.name = "InvalidSelectorError";
|
||||
this.status = "invalid selector";
|
||||
};
|
||||
InvalidSelectorError.prototype = Object.create(WebDriverError.prototype);
|
||||
class InsecureCertificateError extends WebDriverError {
|
||||
constructor (message) {
|
||||
super(message);
|
||||
this.status = "insecure certificate";
|
||||
}
|
||||
}
|
||||
|
||||
this.InvalidSessionIdError = function (msg) {
|
||||
WebDriverError.call(this, msg);
|
||||
this.name = "InvalidSessionIdError";
|
||||
this.status = "invalid session id";
|
||||
};
|
||||
InvalidSessionIdError.prototype = Object.create(WebDriverError.prototype);
|
||||
class InvalidArgumentError extends WebDriverError {
|
||||
constructor (message) {
|
||||
super(message);
|
||||
this.status = "invalid argument";
|
||||
}
|
||||
}
|
||||
|
||||
class InvalidElementStateError extends WebDriverError {
|
||||
constructor (message) {
|
||||
super(message);
|
||||
this.status = "invalid element state";
|
||||
}
|
||||
}
|
||||
|
||||
class InvalidSelectorError extends WebDriverError {
|
||||
constructor (message) {
|
||||
super(message);
|
||||
this.status = "invalid selector";
|
||||
}
|
||||
}
|
||||
|
||||
class InvalidSessionIDError extends WebDriverError {
|
||||
constructor (message) {
|
||||
super(message);
|
||||
this.status = "invalid session id";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an error message for a JavaScript error thrown during
|
||||
* executeScript or executeAsyncScript.
|
||||
*
|
||||
* @param {Error} err
|
||||
* An Error object passed to a catch block or a message.
|
||||
* @param {string=} fnName
|
||||
* The name of the function to use in the stack trace message
|
||||
* (e.g. execute_script).
|
||||
* @param {string=} file
|
||||
* The filename of the test file containing the Marionette
|
||||
* command that caused this error to occur.
|
||||
* @param {number=} line
|
||||
* The line number of the above test file.
|
||||
* @param {string=} script
|
||||
* The JS script being executed in text form.
|
||||
* Creates a richly annotated error for an error situation that occurred
|
||||
* whilst evaluating injected scripts.
|
||||
*/
|
||||
this.JavaScriptError = function (
|
||||
err, fnName = null, file = null, line = null, script = null) {
|
||||
let msg = String(err);
|
||||
let trace = "";
|
||||
class JavaScriptError extends WebDriverError {
|
||||
/**
|
||||
* @param {(string|Error)} x
|
||||
* An Error object instance or a string describing the error
|
||||
* situation.
|
||||
* @param {string=} fnName
|
||||
* Name of the function to use in the stack trace message.
|
||||
* @param {string=} file
|
||||
* Filename of the test file on the client.
|
||||
* @param {number=} line
|
||||
* Line number of |file|.
|
||||
* @param {string=} script
|
||||
* Script being executed, in text form.
|
||||
*/
|
||||
constructor (
|
||||
x,
|
||||
fnName = undefined,
|
||||
file = undefined,
|
||||
line = undefined,
|
||||
script = undefined) {
|
||||
let msg = String(x);
|
||||
let trace = "";
|
||||
|
||||
if (fnName) {
|
||||
trace += fnName;
|
||||
if (file) {
|
||||
trace += ` @${file}`;
|
||||
if (line) {
|
||||
trace += `, line ${line}`;
|
||||
if (fnName) {
|
||||
trace += fnName;
|
||||
if (file) {
|
||||
trace += ` @${file}`;
|
||||
if (line) {
|
||||
trace += `, line ${line}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof err == "object" && "name" in err && "stack" in err) {
|
||||
let jsStack = err.stack.split("\n");
|
||||
let match = jsStack[0].match(/:(\d+):\d+$/);
|
||||
let jsLine = match ? parseInt(match[1]) : 0;
|
||||
if (script) {
|
||||
let src = script.split("\n")[jsLine];
|
||||
trace += "\n" +
|
||||
"inline javascript, line " + jsLine + "\n" +
|
||||
"src: \"" + src + "\"";
|
||||
if (error.isError(x)) {
|
||||
let jsStack = x.stack.split("\n");
|
||||
let match = jsStack[0].match(/:(\d+):\d+$/);
|
||||
let jsLine = match ? parseInt(match[1]) : 0;
|
||||
if (script) {
|
||||
let src = script.split("\n")[jsLine];
|
||||
trace += "\n" +
|
||||
`inline javascript, line ${jsLine}\n` +
|
||||
`src: "${src}"`;
|
||||
}
|
||||
trace += "\nStack:\n" + x.stack;
|
||||
}
|
||||
trace += "\nStack:\n" + String(err.stack);
|
||||
|
||||
super(msg);
|
||||
this.status = "javascript error";
|
||||
this.stack = trace;
|
||||
}
|
||||
}
|
||||
|
||||
WebDriverError.call(this, msg);
|
||||
this.name = "JavaScriptError";
|
||||
this.status = "javascript error";
|
||||
this.stack = trace;
|
||||
};
|
||||
JavaScriptError.prototype = Object.create(WebDriverError.prototype);
|
||||
class NoAlertOpenError extends WebDriverError {
|
||||
constructor (message) {
|
||||
super(message);
|
||||
this.status = "no such alert";
|
||||
}
|
||||
}
|
||||
|
||||
this.NoAlertOpenError = function (msg) {
|
||||
WebDriverError.call(this, msg);
|
||||
this.name = "NoAlertOpenError";
|
||||
this.status = "no such alert";
|
||||
};
|
||||
NoAlertOpenError.prototype = Object.create(WebDriverError.prototype);
|
||||
class NoSuchElementError extends WebDriverError {
|
||||
constructor (message) {
|
||||
super(message);
|
||||
this.status = "no such element";
|
||||
}
|
||||
}
|
||||
|
||||
this.NoSuchElementError = function (msg) {
|
||||
WebDriverError.call(this, msg);
|
||||
this.name = "NoSuchElementError";
|
||||
this.status = "no such element";
|
||||
};
|
||||
NoSuchElementError.prototype = Object.create(WebDriverError.prototype);
|
||||
class NoSuchFrameError extends WebDriverError {
|
||||
constructor (message) {
|
||||
super(message);
|
||||
this.status = "no such frame";
|
||||
}
|
||||
}
|
||||
|
||||
this.NoSuchFrameError = function (msg) {
|
||||
WebDriverError.call(this, msg);
|
||||
this.name = "NoSuchFrameError";
|
||||
this.status = "no such frame";
|
||||
};
|
||||
NoSuchFrameError.prototype = Object.create(WebDriverError.prototype);
|
||||
class NoSuchWindowError extends WebDriverError {
|
||||
constructor (message) {
|
||||
super(message);
|
||||
this.status = "no such window";
|
||||
}
|
||||
}
|
||||
|
||||
this.NoSuchWindowError = function (msg) {
|
||||
WebDriverError.call(this, msg);
|
||||
this.name = "NoSuchWindowError";
|
||||
this.status = "no such window";
|
||||
};
|
||||
NoSuchWindowError.prototype = Object.create(WebDriverError.prototype);
|
||||
class ScriptTimeoutError extends WebDriverError {
|
||||
constructor (message) {
|
||||
super(message);
|
||||
this.status = "script timeout";
|
||||
}
|
||||
}
|
||||
|
||||
this.ScriptTimeoutError = function (msg) {
|
||||
WebDriverError.call(this, msg);
|
||||
this.name = "ScriptTimeoutError";
|
||||
this.status = "script timeout";
|
||||
};
|
||||
ScriptTimeoutError.prototype = Object.create(WebDriverError.prototype);
|
||||
class SessionNotCreatedError extends WebDriverError {
|
||||
constructor (message) {
|
||||
super(message);
|
||||
this.status = "session not created";
|
||||
}
|
||||
}
|
||||
|
||||
this.SessionNotCreatedError = function (msg) {
|
||||
WebDriverError.call(this, msg);
|
||||
this.name = "SessionNotCreatedError";
|
||||
this.status = "session not created";
|
||||
};
|
||||
SessionNotCreatedError.prototype = Object.create(WebDriverError.prototype);
|
||||
class StaleElementReferenceError extends WebDriverError {
|
||||
constructor (message) {
|
||||
super(message);
|
||||
this.status = "stale element reference";
|
||||
}
|
||||
}
|
||||
|
||||
this.StaleElementReferenceError = function (msg) {
|
||||
WebDriverError.call(this, msg);
|
||||
this.name = "StaleElementReferenceError";
|
||||
this.status = "stale element reference";
|
||||
};
|
||||
StaleElementReferenceError.prototype = Object.create(WebDriverError.prototype);
|
||||
class TimeoutError extends WebDriverError {
|
||||
constructor (message) {
|
||||
super(message);
|
||||
this.status = "timeout";
|
||||
}
|
||||
}
|
||||
|
||||
this.TimeoutError = function (msg) {
|
||||
WebDriverError.call(this, msg);
|
||||
this.name = "TimeoutError";
|
||||
this.status = "timeout";
|
||||
};
|
||||
TimeoutError.prototype = Object.create(WebDriverError.prototype);
|
||||
class UnableToSetCookieError extends WebDriverError {
|
||||
constructor (message) {
|
||||
super(message);
|
||||
this.status = "unable to set cookie";
|
||||
}
|
||||
}
|
||||
|
||||
this.UnableToSetCookieError = function (msg) {
|
||||
WebDriverError.call(this, msg);
|
||||
this.name = "UnableToSetCookieError";
|
||||
this.status = "unable to set cookie";
|
||||
};
|
||||
UnableToSetCookieError.prototype = Object.create(WebDriverError.prototype);
|
||||
class UnknownCommandError extends WebDriverError {
|
||||
constructor (message) {
|
||||
super(message);
|
||||
this.status = "unknown command";
|
||||
}
|
||||
}
|
||||
|
||||
this.UnknownCommandError = function (msg) {
|
||||
WebDriverError.call(this, msg);
|
||||
this.name = "UnknownCommandError";
|
||||
this.status = "unknown command";
|
||||
};
|
||||
UnknownCommandError.prototype = Object.create(WebDriverError.prototype);
|
||||
class UnknownError extends WebDriverError {
|
||||
constructor (message) {
|
||||
super(message);
|
||||
this.status = "unknown error";
|
||||
}
|
||||
}
|
||||
|
||||
this.UnknownError = function (msg) {
|
||||
WebDriverError.call(this, msg);
|
||||
this.name = "UnknownError";
|
||||
this.status = "unknown error";
|
||||
};
|
||||
UnknownError.prototype = Object.create(WebDriverError.prototype);
|
||||
|
||||
this.UnsupportedOperationError = function (msg) {
|
||||
WebDriverError.call(this, msg);
|
||||
this.name = "UnsupportedOperationError";
|
||||
this.status = "unsupported operation";
|
||||
};
|
||||
UnsupportedOperationError.prototype = Object.create(WebDriverError.prototype);
|
||||
class UnsupportedOperationError extends WebDriverError {
|
||||
constructor (message) {
|
||||
super(message);
|
||||
this.status = "unsupported operation";
|
||||
}
|
||||
}
|
||||
|
||||
const STATUSES = new Map([
|
||||
["element not accessible", ElementNotAccessibleError],
|
||||
|
|
|
@ -254,15 +254,12 @@ this.Response = class {
|
|||
* propagated.
|
||||
*/
|
||||
sendError(err) {
|
||||
let wd = error.isWebDriverError(err);
|
||||
let we = wd ? err : new WebDriverError(err.message);
|
||||
|
||||
this.error = error.toJson(we);
|
||||
this.error = error.wrap(err).toJSON();
|
||||
this.body = null;
|
||||
this.send();
|
||||
|
||||
// propagate errors that are implementation problems
|
||||
if (!wd) {
|
||||
// propagate errors which are implementation problems
|
||||
if (!error.isWebDriverError(err)) {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -114,7 +114,7 @@ proxy.AsyncMessageChannel = class {
|
|||
break;
|
||||
|
||||
case proxy.AsyncMessageChannel.ReplyType.Error:
|
||||
let err = error.fromJson(msg.json.data);
|
||||
let err = WebDriverError.fromJSON(msg.json.data);
|
||||
reject(err);
|
||||
break;
|
||||
|
||||
|
@ -172,16 +172,24 @@ proxy.AsyncMessageChannel = class {
|
|||
this.sendReply_(uuid, proxy.AsyncMessageChannel.ReplyType.Ok);
|
||||
} else if (error.isError(obj)) {
|
||||
let err = error.wrap(obj);
|
||||
let serr = error.toJson(err);
|
||||
this.sendReply_(uuid, proxy.AsyncMessageChannel.ReplyType.Error, serr);
|
||||
this.sendReply_(uuid, proxy.AsyncMessageChannel.ReplyType.Error, err);
|
||||
} else {
|
||||
this.sendReply_(uuid, proxy.AsyncMessageChannel.ReplyType.Value, obj);
|
||||
}
|
||||
}
|
||||
|
||||
sendReply_(uuid, type, data = undefined) {
|
||||
let path = proxy.AsyncMessageChannel.makePath(uuid);
|
||||
let msg = {type: type, data: data};
|
||||
const path = proxy.AsyncMessageChannel.makePath(uuid);
|
||||
|
||||
let payload;
|
||||
if (data && typeof data.toJSON == "function") {
|
||||
payload = data.toJSON();
|
||||
} else {
|
||||
payload = data;
|
||||
}
|
||||
|
||||
const msg = {type: type, data: payload};
|
||||
|
||||
// here sendAsync is actually the content frame's
|
||||
// sendAsyncMessage(path, message) global
|
||||
this.sendAsync(path, msg);
|
||||
|
|
|
@ -12,7 +12,7 @@ Cu.import("chrome://marionette/content/error.js");
|
|||
add_test(function test_session() {
|
||||
assert.session({sessionId: "foo"});
|
||||
for (let typ of [null, undefined, ""]) {
|
||||
Assert.throws(() => assert.session({sessionId: typ}), InvalidSessionIdError);
|
||||
Assert.throws(() => assert.session({sessionId: typ}), InvalidSessionIDError);
|
||||
}
|
||||
|
||||
run_next_test();
|
||||
|
|
|
@ -43,6 +43,7 @@ add_test(function test_isWebDriverError() {
|
|||
|
||||
ok(error.isWebDriverError(new WebDriverError()));
|
||||
ok(error.isWebDriverError(new InvalidArgumentError()));
|
||||
ok(error.isWebDriverError(new JavaScriptError()));
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
@ -88,23 +89,20 @@ add_test(function test_stringify() {
|
|||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_toJson() {
|
||||
Assert.throws(() => error.toJson(new Error()),
|
||||
/Unserialisable error type: [object Error]/);
|
||||
|
||||
add_test(function test_toJSON() {
|
||||
let e0 = new WebDriverError();
|
||||
let e0s = error.toJson(e0);
|
||||
let e0s = e0.toJSON();
|
||||
equal(e0s.error, "webdriver error");
|
||||
equal(e0s.message, "");
|
||||
equal(e0s.stacktrace, e0.stack);
|
||||
|
||||
let e1 = new WebDriverError("a");
|
||||
let e1s = error.toJson(e1);
|
||||
let e1s = e1.toJSON();
|
||||
equal(e1s.message, e1.message);
|
||||
equal(e1s.stacktrace, e1.stack);
|
||||
|
||||
let e2 = new JavaScriptError("first", "second", "third", "fourth");
|
||||
let e2s = error.toJson(e2);
|
||||
let e2s = e2.toJSON();
|
||||
equal(e2.status, e2s.error);
|
||||
equal(e2.message, e2s.message);
|
||||
ok(e2s.stacktrace.match(/second/));
|
||||
|
@ -114,29 +112,47 @@ add_test(function test_toJson() {
|
|||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_fromJson() {
|
||||
Assert.throws(() => error.fromJson({error: "foo"}),
|
||||
/Undeserialisable error type: foo/);
|
||||
Assert.throws(() => error.fromJson({error: "Error"}),
|
||||
/Undeserialisable error type: Error/);
|
||||
Assert.throws(() => error.fromJson({}),
|
||||
/Undeserialisable error type: undefined/);
|
||||
add_test(function test_fromJSON() {
|
||||
Assert.throws(() => WebDriverError.fromJSON({error: "foo"}),
|
||||
/Not of WebDriverError descent/);
|
||||
Assert.throws(() => WebDriverError.fromJSON({error: "Error"}),
|
||||
/Not of WebDriverError descent/);
|
||||
Assert.throws(() => WebDriverError.fromJSON({}),
|
||||
/Undeserialisable error type/);
|
||||
Assert.throws(() => WebDriverError.fromJSON(undefined),
|
||||
/TypeError/);
|
||||
|
||||
// stacks will be different
|
||||
let e1 = new WebDriverError("1");
|
||||
let e1r = error.fromJson({error: "webdriver error", message: "1"});
|
||||
let e1r = WebDriverError.fromJSON({error: "webdriver error", message: "1"});
|
||||
ok(e1r instanceof WebDriverError);
|
||||
equal(e1r.name, e1.name);
|
||||
equal(e1r.status, e1.status);
|
||||
equal(e1r.message, e1.message);
|
||||
|
||||
// stacks will be different
|
||||
let e2 = new InvalidArgumentError("2");
|
||||
let e2r = error.fromJson({error: "invalid argument", message: "2"});
|
||||
let e2r = WebDriverError.fromJSON({error: "invalid argument", message: "2"});
|
||||
ok(e2r instanceof WebDriverError);
|
||||
ok(e2r instanceof InvalidArgumentError);
|
||||
equal(e2r.name, e2.name);
|
||||
equal(e2r.status, e2.status);
|
||||
equal(e2r.message, e2.message);
|
||||
|
||||
let e3 = new JavaScriptError("first", "second", "third", "fourth");
|
||||
let e3s = error.toJson(e3);
|
||||
deepEqual(e3, error.fromJson(e3s));
|
||||
// test stacks
|
||||
let e3j = {error: "no such element", message: "3", stacktrace: "4"};
|
||||
let e3r = WebDriverError.fromJSON(e3j);
|
||||
ok(e3r instanceof WebDriverError);
|
||||
ok(e3r instanceof NoSuchElementError);
|
||||
equal(e3r.name, "NoSuchElementError");
|
||||
equal(e3r.status, e3j.error);
|
||||
equal(e3r.message, e3j.message);
|
||||
equal(e3r.stack, e3j.stacktrace);
|
||||
|
||||
// parity with toJSON
|
||||
let e4 = new JavaScriptError("first", "second", "third", "fourth");
|
||||
let e4s = e4.toJSON();
|
||||
deepEqual(e4, WebDriverError.fromJSON(e4s));
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
@ -146,7 +162,7 @@ add_test(function test_WebDriverError() {
|
|||
equal("WebDriverError", err.name);
|
||||
equal("foo", err.message);
|
||||
equal("webdriver error", err.status);
|
||||
equal(Error.prototype.toString(), Object.getPrototypeOf(err).toString());
|
||||
ok(err instanceof WebDriverError);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
@ -156,7 +172,7 @@ add_test(function test_ElementNotAccessibleError() {
|
|||
equal("ElementNotAccessibleError", err.name);
|
||||
equal("foo", err.message);
|
||||
equal("element not accessible", err.status);
|
||||
equal(WebDriverError.prototype.toString(), Object.getPrototypeOf(err).toString());
|
||||
ok(err instanceof WebDriverError);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
@ -166,7 +182,7 @@ add_test(function test_ElementNotVisibleError() {
|
|||
equal("ElementNotVisibleError", err.name);
|
||||
equal("foo", err.message);
|
||||
equal("element not visible", err.status);
|
||||
equal(WebDriverError.prototype.toString(), Object.getPrototypeOf(err).toString());
|
||||
ok(err instanceof WebDriverError);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
@ -176,7 +192,7 @@ add_test(function test_InvalidArgumentError() {
|
|||
equal("InvalidArgumentError", err.name);
|
||||
equal("foo", err.message);
|
||||
equal("invalid argument", err.status);
|
||||
equal(WebDriverError.prototype.toString(), Object.getPrototypeOf(err).toString());
|
||||
ok(err instanceof WebDriverError);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
@ -186,7 +202,7 @@ add_test(function test_InvalidElementStateError() {
|
|||
equal("InvalidElementStateError", err.name);
|
||||
equal("foo", err.message);
|
||||
equal("invalid element state", err.status);
|
||||
equal(WebDriverError.prototype.toString(), Object.getPrototypeOf(err).toString());
|
||||
ok(err instanceof WebDriverError);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
@ -196,17 +212,17 @@ add_test(function test_InvalidSelectorError() {
|
|||
equal("InvalidSelectorError", err.name);
|
||||
equal("foo", err.message);
|
||||
equal("invalid selector", err.status);
|
||||
equal(WebDriverError.prototype.toString(), Object.getPrototypeOf(err).toString());
|
||||
ok(err instanceof WebDriverError);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_InvalidSessionIdError() {
|
||||
let err = new InvalidSessionIdError("foo");
|
||||
equal("InvalidSessionIdError", err.name);
|
||||
add_test(function test_InvalidSessionIDError() {
|
||||
let err = new InvalidSessionIDError("foo");
|
||||
equal("InvalidSessionIDError", err.name);
|
||||
equal("foo", err.message);
|
||||
equal("invalid session id", err.status);
|
||||
equal(WebDriverError.prototype.toString(), Object.getPrototypeOf(err).toString());
|
||||
ok(err instanceof WebDriverError);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
@ -216,7 +232,7 @@ add_test(function test_JavaScriptError() {
|
|||
equal("JavaScriptError", err.name);
|
||||
equal("foo", err.message);
|
||||
equal("javascript error", err.status);
|
||||
equal(WebDriverError.prototype.toString(), Object.getPrototypeOf(err).toString());
|
||||
ok(err instanceof WebDriverError);
|
||||
|
||||
equal("undefined", new JavaScriptError(undefined).message);
|
||||
// TODO(ato): Bug 1240550
|
||||
|
@ -234,7 +250,7 @@ add_test(function test_NoAlertOpenError() {
|
|||
equal("NoAlertOpenError", err.name);
|
||||
equal("foo", err.message);
|
||||
equal("no such alert", err.status);
|
||||
equal(WebDriverError.prototype.toString(), Object.getPrototypeOf(err).toString());
|
||||
ok(err instanceof WebDriverError);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
@ -244,7 +260,7 @@ add_test(function test_NoSuchElementError() {
|
|||
equal("NoSuchElementError", err.name);
|
||||
equal("foo", err.message);
|
||||
equal("no such element", err.status);
|
||||
equal(WebDriverError.prototype.toString(), Object.getPrototypeOf(err).toString());
|
||||
ok(err instanceof WebDriverError);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
@ -254,7 +270,7 @@ add_test(function test_NoSuchFrameError() {
|
|||
equal("NoSuchFrameError", err.name);
|
||||
equal("foo", err.message);
|
||||
equal("no such frame", err.status);
|
||||
equal(WebDriverError.prototype.toString(), Object.getPrototypeOf(err).toString());
|
||||
ok(err instanceof WebDriverError);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
@ -264,7 +280,7 @@ add_test(function test_NoSuchWindowError() {
|
|||
equal("NoSuchWindowError", err.name);
|
||||
equal("foo", err.message);
|
||||
equal("no such window", err.status);
|
||||
equal(WebDriverError.prototype.toString(), Object.getPrototypeOf(err).toString());
|
||||
ok(err instanceof WebDriverError);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
@ -274,7 +290,7 @@ add_test(function test_ScriptTimeoutError() {
|
|||
equal("ScriptTimeoutError", err.name);
|
||||
equal("foo", err.message);
|
||||
equal("script timeout", err.status);
|
||||
equal(WebDriverError.prototype.toString(), Object.getPrototypeOf(err).toString());
|
||||
ok(err instanceof WebDriverError);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
@ -284,7 +300,7 @@ add_test(function test_SessionNotCreatedError() {
|
|||
equal("SessionNotCreatedError", err.name);
|
||||
equal("foo", err.message);
|
||||
equal("session not created", err.status);
|
||||
equal(WebDriverError.prototype.toString(), Object.getPrototypeOf(err).toString());
|
||||
ok(err instanceof WebDriverError);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
@ -294,7 +310,7 @@ add_test(function test_StaleElementReferenceError() {
|
|||
equal("StaleElementReferenceError", err.name);
|
||||
equal("foo", err.message);
|
||||
equal("stale element reference", err.status);
|
||||
equal(WebDriverError.prototype.toString(), Object.getPrototypeOf(err).toString());
|
||||
ok(err instanceof WebDriverError);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
@ -304,7 +320,7 @@ add_test(function test_TimeoutError() {
|
|||
equal("TimeoutError", err.name);
|
||||
equal("foo", err.message);
|
||||
equal("timeout", err.status);
|
||||
equal(WebDriverError.prototype.toString(), Object.getPrototypeOf(err).toString());
|
||||
ok(err instanceof WebDriverError);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
@ -314,7 +330,7 @@ add_test(function test_UnableToSetCookieError() {
|
|||
equal("UnableToSetCookieError", err.name);
|
||||
equal("foo", err.message);
|
||||
equal("unable to set cookie", err.status);
|
||||
equal(WebDriverError.prototype.toString(), Object.getPrototypeOf(err).toString());
|
||||
ok(err instanceof WebDriverError);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
@ -324,7 +340,7 @@ add_test(function test_UnknownCommandError() {
|
|||
equal("UnknownCommandError", err.name);
|
||||
equal("foo", err.message);
|
||||
equal("unknown command", err.status);
|
||||
equal(WebDriverError.prototype.toString(), Object.getPrototypeOf(err).toString());
|
||||
ok(err instanceof WebDriverError);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
@ -334,7 +350,7 @@ add_test(function test_UnknownError() {
|
|||
equal("UnknownError", err.name);
|
||||
equal("foo", err.message);
|
||||
equal("unknown error", err.status);
|
||||
equal(WebDriverError.prototype.toString(), Object.getPrototypeOf(err).toString());
|
||||
ok(err instanceof WebDriverError);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
@ -344,7 +360,7 @@ add_test(function test_UnsupportedOperationError() {
|
|||
equal("UnsupportedOperationError", err.name);
|
||||
equal("foo", err.message);
|
||||
equal("unsupported operation", err.status);
|
||||
equal(WebDriverError.prototype.toString(), Object.getPrototypeOf(err).toString());
|
||||
ok(err instanceof WebDriverError);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
|
|
@ -143,7 +143,7 @@ add_test(function test_Response_send() {
|
|||
add_test(function test_Response_sendError() {
|
||||
let err = new WebDriverError();
|
||||
let resp = new Response(42, r => {
|
||||
equal(error.toJson(err).error, r.error.error);
|
||||
equal(err.toJSON().error, r.error.error);
|
||||
equal(null, r.body);
|
||||
equal(false, r.sent);
|
||||
});
|
||||
|
|
Загрузка…
Ссылка в новой задаче