зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1739976 - [webdriver-bidi] Add basic support for payload deserialization. r=webdriver-reviewers,jgraham,jdescottes
Differential Revision: https://phabricator.services.mozilla.com/D133677
This commit is contained in:
Родитель
a6679a0579
Коммит
a1b9267fa5
|
@ -4,13 +4,15 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
var EXPORTED_SYMBOLS = ["serialize"];
|
||||
var EXPORTED_SYMBOLS = ["deserialize", "serialize"];
|
||||
|
||||
const { XPCOMUtils } = ChromeUtils.import(
|
||||
"resource://gre/modules/XPCOMUtils.jsm"
|
||||
);
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetters(this, {
|
||||
assert: "chrome://remote/content/shared/webdriver/Assert.jsm",
|
||||
InvalidArgumentError: "chrome://remote/content/shared/webdriver/Errors.jsm",
|
||||
Log: "chrome://remote/content/shared/Log.jsm",
|
||||
});
|
||||
|
||||
|
@ -18,6 +20,71 @@ XPCOMUtils.defineLazyGetter(this, "logger", () =>
|
|||
Log.get(Log.TYPES.WEBDRIVER_BIDI)
|
||||
);
|
||||
|
||||
/**
|
||||
* Deserialize a local value.
|
||||
*
|
||||
* @see https://w3c.github.io/webdriver-bidi/#deserialize-local-value
|
||||
*
|
||||
* @param {Object} serializedValue
|
||||
* Value of any type to be deserialized.
|
||||
*
|
||||
* @returns {Object} Deserialized representation of the value.
|
||||
*/
|
||||
function deserialize(serializedValue) {
|
||||
const { objectId, type, value } = serializedValue;
|
||||
|
||||
if (type !== undefined) {
|
||||
assert.string(type, `Expected "type" to be a string, got ${type}`);
|
||||
}
|
||||
|
||||
// With an objectId present deserialize as remote reference.
|
||||
if (objectId !== undefined) {
|
||||
assert.string(
|
||||
objectId,
|
||||
`Expected "objectId" to be a string, got ${objectId}`
|
||||
);
|
||||
|
||||
// TODO: Implement deserialization of remote references (bug 1693838)
|
||||
logger.warn(`Unsupported type remote reference with objectId ${objectId}`);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Primitive protocol values
|
||||
switch (type) {
|
||||
case "undefined":
|
||||
return undefined;
|
||||
case "null":
|
||||
return null;
|
||||
case "string":
|
||||
assert.string(value, `Expected "value" to be a string, got ${value}`);
|
||||
return value;
|
||||
case "number":
|
||||
// If value is already a number return its value.
|
||||
if (typeof value === "number") {
|
||||
return value;
|
||||
}
|
||||
|
||||
// Otherwise it has to be one of the special strings
|
||||
assert.in(value, ["NaN", "-0", "+Infinity", "-Infinity"]);
|
||||
return Number(value);
|
||||
case "boolean":
|
||||
assert.boolean(value, `Expected "value" to be a boolean, got ${value}`);
|
||||
return value;
|
||||
case "bigint":
|
||||
assert.string(value, `Expected "value" to be a string, got ${value}`);
|
||||
try {
|
||||
return BigInt(value);
|
||||
} catch (e) {
|
||||
throw new InvalidArgumentError(
|
||||
`Failed to deserialize value as BigInt: ${value}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
logger.warn(`Unsupported type for local value ${type}`);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize a value as a remote value.
|
||||
*
|
||||
|
@ -31,31 +98,25 @@ XPCOMUtils.defineLazyGetter(this, "logger", () =>
|
|||
function serialize(value /*, maxDepth, nodeDetails, knownObjects */) {
|
||||
const type = typeof value;
|
||||
|
||||
let remoteValue;
|
||||
|
||||
// Primitive protocol values
|
||||
if (type == "undefined") {
|
||||
remoteValue = { type };
|
||||
return { type };
|
||||
} else if (Object.is(value, null)) {
|
||||
remoteValue = { type: "null" };
|
||||
|
||||
// Special numbers
|
||||
return { type: "null" };
|
||||
} else if (Object.is(value, NaN)) {
|
||||
remoteValue = { type: "number", value: "NaN" };
|
||||
return { type: "number", value: "NaN" };
|
||||
} else if (Object.is(value, -0)) {
|
||||
remoteValue = { type: "number", value: "-0" };
|
||||
return { type: "number", value: "-0" };
|
||||
} else if (Object.is(value, Infinity)) {
|
||||
remoteValue = { type: "number", value: "+Infinity" };
|
||||
return { type: "number", value: "+Infinity" };
|
||||
} else if (Object.is(value, -Infinity)) {
|
||||
remoteValue = { type: "number", value: "-Infinity" };
|
||||
return { type: "number", value: "-Infinity" };
|
||||
} else if (type == "bigint") {
|
||||
remoteValue = { type, value: value.toString() };
|
||||
|
||||
// values that are directly represented in the serialization
|
||||
return { type, value: value.toString() };
|
||||
} else if (["boolean", "number", "string"].includes(type)) {
|
||||
remoteValue = { type, value };
|
||||
} else {
|
||||
logger.warn(`Unsupported type for remote value: ${value.toString()}`);
|
||||
return { type, value };
|
||||
}
|
||||
|
||||
return remoteValue;
|
||||
logger.warn(`Unsupported type for remote value: ${value.toString()}`);
|
||||
return undefined;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const PRIMITIVE_TYPES = [
|
||||
{ value: undefined, serialized: { type: "undefined" } },
|
||||
{ value: null, serialized: { type: "null" } },
|
||||
{ value: "foo", serialized: { type: "string", value: "foo" } },
|
||||
{ value: Number.NaN, serialized: { type: "number", value: "NaN" } },
|
||||
{ value: -0, serialized: { type: "number", value: "-0" } },
|
||||
{
|
||||
value: Number.POSITIVE_INFINITY,
|
||||
serialized: { type: "number", value: "+Infinity" },
|
||||
},
|
||||
{
|
||||
value: Number.NEGATIVE_INFINITY,
|
||||
serialized: { type: "number", value: "-Infinity" },
|
||||
},
|
||||
{ value: 42, serialized: { type: "number", value: 42 } },
|
||||
{ value: false, serialized: { type: "boolean", value: false } },
|
||||
{ value: 42n, serialized: { type: "bigint", value: "42" } },
|
||||
];
|
||||
|
||||
const { deserialize, serialize } = ChromeUtils.import(
|
||||
"chrome://remote/content/webdriver-bidi/RemoteValue.jsm"
|
||||
);
|
||||
|
||||
add_test(function test_deserializePrimitiveTypes() {
|
||||
for (const type of PRIMITIVE_TYPES) {
|
||||
const { value: expectedValue, serialized } = type;
|
||||
const value = deserialize(serialized);
|
||||
|
||||
info(`Checking '${type}'`);
|
||||
|
||||
if (serialized.value == "NaN") {
|
||||
ok(Number.isNaN(value), `Got expected value for ${serialized}`);
|
||||
} else {
|
||||
Assert.strictEqual(
|
||||
value,
|
||||
expectedValue,
|
||||
`Got expected value for ${serialized}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_deserializePrimitiveTypesInvalidValues() {
|
||||
const invalidValues = [
|
||||
{ type: "bigint", values: [undefined, null, false, "foo", [], {}] },
|
||||
{ type: "boolean", values: [undefined, null, 42, "foo", [], {}] },
|
||||
{
|
||||
type: "number",
|
||||
values: [undefined, null, false, "43", [], {}],
|
||||
},
|
||||
{ type: "string", values: [undefined, null, false, 42, [], {}] },
|
||||
];
|
||||
|
||||
for (const invalidValue of invalidValues) {
|
||||
const { type, values } = invalidValue;
|
||||
|
||||
for (const value of values) {
|
||||
info(`Checking '${type}' with value ${value}`);
|
||||
|
||||
Assert.throws(
|
||||
() => deserialize({ type, value }),
|
||||
/InvalidArgument/,
|
||||
`Got expected error for type ${type} and value ${value}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_serializePrimitiveTypes() {
|
||||
for (const type of PRIMITIVE_TYPES) {
|
||||
const { value, serialized } = type;
|
||||
|
||||
const serializedValue = serialize(value);
|
||||
for (const prop in serialized) {
|
||||
info(`Checking '${serialized.type}'`);
|
||||
|
||||
Assert.strictEqual(
|
||||
serializedValue[prop],
|
||||
serialized[prop],
|
||||
`Got expected value for property ${prop}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
run_next_test();
|
||||
});
|
|
@ -2,4 +2,5 @@
|
|||
# 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/.
|
||||
|
||||
[test_RemoteValue.js]
|
||||
[test_WebDriverBiDiConnection.js]
|
||||
|
|
Загрузка…
Ссылка в новой задаче