Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

/* Any copyright is dedicated to the Public Domain.
"use strict";
// Test the Runtime remote object
add_task(async function ({ client }) {
const firstContext = await testRuntimeEnable(client);
const contextId = firstContext.id;
await testGetOwnSimpleProperties(client, contextId);
await testGetCustomProperty(client, contextId);
await testGetPrototypeProperties(client, contextId);
await testGetGetterSetterProperties(client, contextId);
});
async function testRuntimeEnable({ Runtime }) {
// Enable watching for new execution context
await Runtime.enable();
info("Runtime domain has been enabled");
// Calling Runtime.enable will emit executionContextCreated for the existing contexts
const { context } = await Runtime.executionContextCreated();
ok(!!context.id, "The execution context has an id");
ok(context.auxData.isDefault, "The execution context is the default one");
ok(!!context.auxData.frameId, "The execution context has a frame id set");
return context;
}
async function testGetOwnSimpleProperties({ Runtime }, contextId) {
const { result } = await Runtime.evaluate({
contextId,
expression: "({ bool: true, fun() {}, int: 1, object: {}, string: 'foo' })",
});
is(result.subtype, undefined, "JS Object has no subtype");
is(result.type, "object", "The type is correct");
ok(!!result.objectId, "Got an object id");
const { result: result2 } = await Runtime.getProperties({
objectId: result.objectId,
ownProperties: true,
});
is(
result2.length,
5,
"ownProperties=true allows to iterate only over direct object properties (i.e. ignore prototype)"
);
result2.sort((a, b) => a.name > b.name);
is(result2[0].name, "bool");
is(result2[0].configurable, true);
is(result2[0].enumerable, true);
is(result2[0].writable, true);
is(result2[0].value.type, "boolean");
is(result2[0].value.value, true);
is(result2[0].isOwn, true);
is(result2[1].name, "fun");
is(result2[1].configurable, true);
is(result2[1].enumerable, true);
is(result2[1].writable, true);
is(result2[1].value.type, "function");
ok(!!result2[1].value.objectId);
is(result2[1].isOwn, true);
is(result2[2].name, "int");
is(result2[2].configurable, true);
is(result2[2].enumerable, true);
is(result2[2].writable, true);
is(result2[2].value.type, "number");
is(result2[2].value.value, 1);
is(result2[2].isOwn, true);
is(result2[3].name, "object");
is(result2[3].configurable, true);
is(result2[3].enumerable, true);
is(result2[3].writable, true);
is(result2[3].value.type, "object");
ok(!!result2[3].value.objectId);
is(result2[3].isOwn, true);
is(result2[4].name, "string");
is(result2[4].configurable, true);
is(result2[4].enumerable, true);
is(result2[4].writable, true);
is(result2[4].value.type, "string");
is(result2[4].value.value, "foo");
is(result2[4].isOwn, true);
}
async function testGetPrototypeProperties({ Runtime }, contextId) {
const { result } = await Runtime.evaluate({
contextId,
expression: "({ foo: 42 })",
});
is(result.subtype, undefined, "JS Object has no subtype");
is(result.type, "object", "The type is correct");
ok(!!result.objectId, "Got an object id");
const { result: result2 } = await Runtime.getProperties({
objectId: result.objectId,
ownProperties: false,
});
Assert.greater(
result2.length,
1,
"We have more properties than just the object one"
);
const foo = result2.find(p => p.name == "foo");
ok(foo, "The object property is described");
ok(foo.isOwn, "and is reported as 'own' property");
const toString = result2.find(p => p.name == "toString");
ok(
toString,
"Function from Object's prototype are also described like toString"
);
ok(!toString.isOwn, "but are reported as not being an 'own' property");
}
async function testGetGetterSetterProperties({ Runtime }, contextId) {
const { result } = await Runtime.evaluate({
contextId,
expression:
"({ get prop() { return this.x; }, set prop(v) { this.x = v; } })",
});
is(result.subtype, undefined, "JS Object has no subtype");
is(result.type, "object", "The type is correct");
ok(!!result.objectId, "Got an object id");
const { result: result2 } = await Runtime.getProperties({
objectId: result.objectId,
ownProperties: true,
});
is(result2.length, 1);
is(result2[0].name, "prop");
is(result2[0].configurable, true);
is(result2[0].enumerable, true);
is(
result2[0].writable,
undefined,
"writable is only set for data properties"
);
is(result2[0].get.type, "function");
ok(!!result2[0].get.objectId);
is(result2[0].set.type, "function");
ok(!!result2[0].set.objectId);
is(result2[0].isOwn, true);
const { result: result3 } = await Runtime.callFunctionOn({
executionContextId: contextId,
functionDeclaration: "(set, get) => { set(42); return get(); }",
arguments: [
{ objectId: result2[0].set.objectId },
{ objectId: result2[0].get.objectId },
],
});
is(result3.type, "number", "The type is correct");
is(result3.subtype, undefined, "The subtype is undefined for numbers");
is(result3.value, 42, "The getter returned the value set by the setter");
}
async function testGetCustomProperty({ Runtime }, contextId) {
const { result } = await Runtime.evaluate({
contextId,
expression: `const obj = {}; Object.defineProperty(obj, "prop", { value: 42 }); obj`,
});
is(result.subtype, undefined, "JS Object has no subtype");
is(result.type, "object", "The type is correct");
ok(!!result.objectId, "Got an object id");
const { result: result2 } = await Runtime.getProperties({
objectId: result.objectId,
ownProperties: true,
});
is(result2.length, 1, "We only get the one object's property");
is(result2[0].name, "prop");
is(result2[0].configurable, false);
is(result2[0].enumerable, false);
is(result2[0].writable, false);
is(result2[0].value.type, "number");
is(result2[0].value.value, 42);
is(result2[0].isOwn, true);
}