diff options
Diffstat (limited to 'remote/test/browser/runtime/browser_getProperties.js')
-rw-r--r-- | remote/test/browser/runtime/browser_getProperties.js | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/remote/test/browser/runtime/browser_getProperties.js b/remote/test/browser/runtime/browser_getProperties.js new file mode 100644 index 0000000000..84229db10e --- /dev/null +++ b/remote/test/browser/runtime/browser_getProperties.js @@ -0,0 +1,184 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"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, + }); + ok(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); +} |