const hiddenFrames = require("hidden-frame"); const xulApp = require("xul-app"); const { Loader } = require('./helpers'); /* * Utility function that allow to easily run a proxy test with a clean * new HTML document. See first unit test for usage. */ function createProxyTest(html, callback) { return function (test) { test.waitUntilDone(); let url = 'data:text/html,' + encodeURI(html); let hiddenFrame = hiddenFrames.add(hiddenFrames.HiddenFrame({ onReady: function () { function onDOMReady() { hiddenFrame.element.removeEventListener("DOMContentLoaded", onDOMReady, false); let xrayWindow = hiddenFrame.element.contentWindow; let rawWindow = xrayWindow.wrappedJSObject; let done = false; let helper = { xrayWindow: xrayWindow, rawWindow: rawWindow, createWorker: function (contentScript) { return createWorker(test, xrayWindow, contentScript, helper.done); }, done: function () { if (done) return; done = true; hiddenFrames.remove(hiddenFrame); test.done(); } } callback(helper, test); } hiddenFrame.element.addEventListener("DOMContentLoaded", onDOMReady, false); hiddenFrame.element.setAttribute("src", url); } })); }; } function createWorker(test, xrayWindow, contentScript, done) { // We have to use Sandboxed loader in order to get access to the private // unlock key `PRIVATE_KEY`. This key should not be used anywhere else. // See `PRIVATE_KEY` definition in worker.js let loader = Loader(module); let Worker = loader.require("api-utils/content/worker").Worker; let key = loader.sandbox("api-utils/content/worker").PRIVATE_KEY; let worker = Worker({ exposeUnlockKey : key, window: xrayWindow, contentScript: [ 'new ' + function () { assert = function assert(v, msg) { self.port.emit("assert", {assertion:v, msg:msg}); } done = function done() { self.port.emit("done"); } }, contentScript ] }); worker.port.on("done", done); worker.port.on("assert", function (data) { test.assert(data.assertion, data.msg); }); return worker; } /* Examples for the `createProxyTest` uses */ let html = ""; exports.testCreateProxyTest = createProxyTest(html, function (helper, test) { // You can get access to regular `test` object in second argument of // `createProxyTest` method: test.assert(helper.rawWindow.documentGlobal, "You have access to a raw window reference via `helper.rawWindow`"); test.assert(!("documentGlobal" in helper.xrayWindow), "You have access to an XrayWrapper reference via `helper.xrayWindow`"); // If you do not create a Worker, you have to call helper.done(), // in order to say when your test is finished helper.done(); }); exports.testCreateProxyTestWithWorker = createProxyTest("", function (helper) { helper.createWorker( "new " + function WorkerScope() { assert(true, "You can do assertions in your content script"); // And if you create a worker, you either have to call `done` // from content script or helper.done() done(); } ); }); exports.testCreateProxyTestWithEvents = createProxyTest("", function (helper, test) { let worker = helper.createWorker( "new " + function WorkerScope() { self.port.emit("foo"); } ); worker.port.on("foo", function () { test.pass("You can use events"); // And terminate your test with helper.done: helper.done(); }); }); // Verify that the attribute `exposeUnlockKey`, that allow this test // to identify proxies, works correctly. // See `PRIVATE_KEY` definition in worker.js exports.testKeyAccess = createProxyTest("", function(helper) { helper.createWorker( 'new ' + function ContentScriptScope() { assert("UNWRAP_ACCESS_KEY" in window, "have access to `UNWRAP_ACCESS_KEY`"); done(); } ); }); // Bug 714778: There was some issue around `toString` functions // that ended up being shared between content scripts exports.testSharedToStringProxies = createProxyTest("", function(helper) { let worker = helper.createWorker( 'new ' + function ContentScriptScope() { assert(document.location.toString() == "data:text/html,", "document.location.toString()"); self.postMessage("next"); } ); worker.on("message", function () { helper.createWorker( 'new ' + function ContentScriptScope2() { assert(document.location.toString() == "data:text/html,", "document.location.toString()"); done(); } ); }); }); // Ensure that postMessage is working correctly across documents with an iframe let html = '