"use strict"; /* globals browser */ AddonTestUtils.init(this); add_task(async function setup() { AddonTestUtils.overrideCertDB(); await ExtensionTestUtils.startAddonManager(); }); let fooExperimentAPIs = { foo: { schema: "schema.json", parent: { scopes: ["addon_parent"], script: "parent.js", paths: [["experiments", "foo", "parent"]], }, child: { scopes: ["addon_child"], script: "child.js", paths: [["experiments", "foo", "child"]], }, }, }; let fooExperimentFiles = { "schema.json": JSON.stringify([ { "namespace": "experiments.foo", "types": [ { "id": "Meh", "type": "object", "properties": {}, }, ], "functions": [ { "name": "parent", "type": "function", "async": true, "parameters": [], }, { "name": "child", "type": "function", "parameters": [], "returns": {"type": "string"}, }, ], }, ]), /* globals ExtensionAPI */ "parent.js": () => { this.foo = class extends ExtensionAPI { getAPI(context) { return { experiments: { foo: { parent() { return Promise.resolve("parent"); }, }, }, }; } }; }, "child.js": () => { this.foo = class extends ExtensionAPI { getAPI(context) { return { experiments: { foo: { child() { return "child"; }, }, }, }; } }; }, }; async function testFooExperiment() { browser.test.assertEq("object", typeof browser.experiments, "typeof browser.experiments"); browser.test.assertEq("object", typeof browser.experiments.foo, "typeof browser.experiments.foo"); browser.test.assertEq("function", typeof browser.experiments.foo.child, "typeof browser.experiments.foo.child"); browser.test.assertEq("function", typeof browser.experiments.foo.parent, "typeof browser.experiments.foo.parent"); browser.test.assertEq("child", browser.experiments.foo.child(), "foo.child()"); browser.test.assertEq("parent", await browser.experiments.foo.parent(), "await foo.parent()"); } async function testFooFailExperiment() { browser.test.assertEq("object", typeof browser.experiments, "typeof browser.experiments"); browser.test.assertEq("undefined", typeof browser.experiments.foo, "typeof browser.experiments.foo"); } add_task(async function test_bundled_experiments() { let testCases = [ {isSystem: true, temporarilyInstalled: true, shouldHaveExperiments: true}, {isSystem: true, temporarilyInstalled: false, shouldHaveExperiments: true}, {isPrivileged: true, temporarilyInstalled: true, shouldHaveExperiments: true}, {isPrivileged: true, temporarilyInstalled: false, shouldHaveExperiments: true}, {isPrivileged: false, temporarilyInstalled: true, shouldHaveExperiments: AppConstants.MOZ_ALLOW_LEGACY_EXTENSIONS}, {isPrivileged: false, temporarilyInstalled: false, shouldHaveExperiments: false}, ]; async function background(shouldHaveExperiments) { if (shouldHaveExperiments) { await testFooExperiment(); } else { await testFooFailExperiment(); } browser.test.notifyPass("background.experiments.foo"); } for (let testCase of testCases) { let extension = ExtensionTestUtils.loadExtension({ isPrivileged: testCase.isPrivileged, isSystem: testCase.isSystem, temporarilyInstalled: testCase.temporarilyInstalled, manifest: { experiment_apis: fooExperimentAPIs, }, background: ` ${testFooExperiment} ${testFooFailExperiment} (${background})(${testCase.shouldHaveExperiments}); `, files: fooExperimentFiles, }); await extension.startup(); await extension.awaitFinish("background.experiments.foo"); await extension.unload(); } }); add_task(async function test_unbundled_experiments() { async function background() { await testFooExperiment(); browser.test.assertEq("object", typeof browser.experiments.crunk, "typeof browser.experiments.crunk"); browser.test.assertEq("function", typeof browser.experiments.crunk.child, "typeof browser.experiments.crunk.child"); browser.test.assertEq("function", typeof browser.experiments.crunk.parent, "typeof browser.experiments.crunk.parent"); browser.test.assertEq("crunk-child", browser.experiments.crunk.child(), "crunk.child()"); browser.test.assertEq("crunk-parent", await browser.experiments.crunk.parent(), "await crunk.parent()"); browser.test.notifyPass("background.experiments.crunk"); } let extension = ExtensionTestUtils.loadExtension({ isPrivileged: true, manifest: { experiment_apis: fooExperimentAPIs, permissions: ["experiments.crunk"], }, background: ` ${testFooExperiment} (${background})(); `, files: fooExperimentFiles, }); let apiExtension = ExtensionTestUtils.loadExtension({ isPrivileged: true, manifest: { applications: {gecko: {id: "crunk@experiments.addons.mozilla.org"}}, experiment_apis: { crunk: { schema: "schema.json", parent: { scopes: ["addon_parent"], script: "parent.js", paths: [["experiments", "crunk", "parent"]], }, child: { scopes: ["addon_child"], script: "child.js", paths: [["experiments", "crunk", "child"]], }, }, }, }, files: { "schema.json": JSON.stringify([ { "namespace": "experiments.crunk", "types": [ { "id": "Meh", "type": "object", "properties": {}, }, ], "functions": [ { "name": "parent", "type": "function", "async": true, "parameters": [], }, { "name": "child", "type": "function", "parameters": [], "returns": {"type": "string"}, }, ], }, ]), "parent.js": () => { this.crunk = class extends ExtensionAPI { getAPI(context) { return { experiments: { crunk: { parent() { return Promise.resolve("crunk-parent"); }, }, }, }; } }; }, "child.js": () => { this.crunk = class extends ExtensionAPI { getAPI(context) { return { experiments: { crunk: { child() { return "crunk-child"; }, }, }, }; } }; }, }, }); await apiExtension.startup(); await extension.startup(); await extension.awaitFinish("background.experiments.crunk"); await extension.unload(); await apiExtension.unload(); });