diff options
Diffstat (limited to 'toolkit/components/extensions/test/xpcshell/test_ext_schemas_interactive.js')
-rw-r--r-- | toolkit/components/extensions/test/xpcshell/test_ext_schemas_interactive.js | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/toolkit/components/extensions/test/xpcshell/test_ext_schemas_interactive.js b/toolkit/components/extensions/test/xpcshell/test_ext_schemas_interactive.js new file mode 100644 index 0000000000..986dc74bc5 --- /dev/null +++ b/toolkit/components/extensions/test/xpcshell/test_ext_schemas_interactive.js @@ -0,0 +1,173 @@ +"use strict"; + +const { ExtensionProcessScript } = ChromeUtils.importESModule( + "resource://gre/modules/ExtensionProcessScript.sys.mjs" +); + +let experimentAPIs = { + userinputtest: { + schema: "schema.json", + parent: { + scopes: ["addon_parent"], + script: "parent.js", + paths: [["userinputtest"]], + }, + child: { + scopes: ["addon_child"], + script: "child.js", + paths: [["userinputtest", "child"]], + }, + }, +}; + +let experimentFiles = { + "schema.json": JSON.stringify([ + { + namespace: "userinputtest", + functions: [ + { + name: "test", + type: "function", + async: true, + requireUserInput: true, + parameters: [], + }, + { + name: "child", + type: "function", + async: true, + requireUserInput: true, + parameters: [], + }, + ], + }, + ]), + + /* globals ExtensionAPI */ + "parent.js": () => { + this.userinputtest = class extends ExtensionAPI { + getAPI(context) { + return { + userinputtest: { + test() {}, + }, + }; + } + }; + }, + + "child.js": () => { + this.userinputtest = class extends ExtensionAPI { + getAPI(context) { + return { + userinputtest: { + child() {}, + }, + }; + } + }; + }, +}; + +// Set the "handlingUserInput" flag for the given extension's background page. +// Returns an RAIIHelper that should be destruct()ed eventually. +function setHandlingUserInput(extension) { + let extensionChild = ExtensionProcessScript.getExtensionChild(extension.id); + let bgwin = null; + for (let view of extensionChild.views) { + if (view.viewType == "background") { + bgwin = view.contentWindow; + break; + } + } + notEqual(bgwin, null, "Found background window for the test extension"); + let winutils = bgwin.windowUtils; + return winutils.setHandlingUserInput(true); +} + +// Test that the schema requireUserInput flag works correctly for +// proxied api implementations. +add_task(async function test_proxy() { + let extension = ExtensionTestUtils.loadExtension({ + isPrivileged: true, + background() { + browser.test.onMessage.addListener(async () => { + try { + await browser.userinputtest.test(); + browser.test.sendMessage("result", null); + } catch (err) { + browser.test.sendMessage("result", err.message); + } + }); + }, + manifest: { + permissions: ["experiments.userinputtest"], + experiment_apis: experimentAPIs, + }, + files: experimentFiles, + }); + + await extension.startup(); + + extension.sendMessage("test"); + let result = await extension.awaitMessage("result"); + ok( + /test may only be called from a user input handler/.test(result), + `function failed when not called from a user input handler: ${result}` + ); + + let handle = setHandlingUserInput(extension); + extension.sendMessage("test"); + result = await extension.awaitMessage("result"); + equal( + result, + null, + "function succeeded when called from a user input handler" + ); + handle.destruct(); + + await extension.unload(); +}); + +// Test that the schema requireUserInput flag works correctly for +// non-proxied api implementations. +add_task(async function test_local() { + let extension = ExtensionTestUtils.loadExtension({ + isPrivileged: true, + background() { + browser.test.onMessage.addListener(async () => { + try { + await browser.userinputtest.child(); + browser.test.sendMessage("result", null); + } catch (err) { + browser.test.sendMessage("result", err.message); + } + }); + }, + manifest: { + experiment_apis: experimentAPIs, + }, + files: experimentFiles, + }); + + await extension.startup(); + + extension.sendMessage("test"); + let result = await extension.awaitMessage("result"); + ok( + /child may only be called from a user input handler/.test(result), + `function failed when not called from a user input handler: ${result}` + ); + + let handle = setHandlingUserInput(extension); + extension.sendMessage("test"); + result = await extension.awaitMessage("result"); + equal( + result, + null, + "function succeeded when called from a user input handler" + ); + handle.destruct(); + + await extension.unload(); +}); |