/* 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 (assert, done) { 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 isDone = false; let helper = { xrayWindow: xrayWindow, rawWindow: rawWindow, createWorker: function (contentScript) { return createWorker(assert, xrayWindow, contentScript, helper.done); }, done: function () { if (isDone) return; isDone = true; hiddenFrames.remove(hiddenFrame); done(); } } callback(helper, assert); } hiddenFrame.element.addEventListener("DOMContentLoaded", onDOMReady, false); hiddenFrame.element.setAttribute("src", url); } })); }; } function createWorker(assert, 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) { assert.ok(data.assertion, data.msg); }); return worker; } /* Examples for the `createProxyTest` uses */ let html = ""; exports["test Create Proxy Test"] = createProxyTest(html, function (helper, assert) { // You can get access to regular `test` object in second argument of // `createProxyTest` method: assert.ok(helper.rawWindow.documentGlobal, "You have access to a raw window reference via `helper.rawWindow`"); assert.ok(!("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["test Create Proxy Test With Worker"] = 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["test Create Proxy Test With Events"] = createProxyTest("", function (helper, assert) { let worker = helper.createWorker( "new " + function WorkerScope() { self.port.emit("foo"); } ); worker.port.on("foo", function () { assert.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["test Key Access"] = 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["test Shared To String Proxies"] = 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 = '