/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ const hiddenFrames = require("sdk/frame/hidden-frame"); const xulApp = require("sdk/system/xul-app"); const USE_JS_PROXIES = !xulApp.versionInRange(xulApp.platformVersion, "17.0a2", "*"); const { Loader } = require('sdk/test/loader'); /* * 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;charset=utf-8,' + 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("sdk/content/worker").Worker; let key = loader.sandbox("sdk/content/worker").PRIVATE_KEY; let worker = Worker({ exposeUnlockKey : USE_JS_PROXIES ? key : null, 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(); }); }); if (USE_JS_PROXIES) { // 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() { // We ensure that `toString` can't be modified so that nothing could // leak to/from the document and between content scripts // It only applies to JS proxies, there isn't any such issue with xrays. //document.location.toString = function foo() {}; document.location.toString.foo = "bar"; if ('UNWRAP_ACCESS_KEY' in window) assert(!("foo" in document.location.toString), "document.location.toString can't be modified"); else assert("foo" in document.location.toString, "document.location.toString can be modified"); assert(document.location.toString() == "data:text/html;charset=utf-8,", "First document.location.toString()"); self.postMessage("next"); } ); worker.on("message", function () { helper.createWorker( 'new ' + function ContentScriptScope2() { assert(!("foo" in document.location.toString), "document.location.toString is different for each content script"); assert(document.location.toString() == "data:text/html;charset=utf-8,", "Second document.location.toString()"); done(); } ); }); }); // Ensure that postMessage is working correctly across documents with an iframe let html = '