/* 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 { create: makeFrame } = require("sdk/frame/utils"); const { window } = require("sdk/addon/window"); const { Loader } = require('sdk/test/loader'); const { URL } = require("sdk/url"); const testURI = require("sdk/self").data.url("test.html"); const testHost = URL(testURI).scheme + '://' + URL(testURI).host; /* * 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,' + encodeURIComponent(html); let principalLoaded = false; let element = makeFrame(window.document, { nodeName: "iframe", type: "content", allowJavascript: true, allowPlugins: true, allowAuth: true, uri: testURI }); element.addEventListener("DOMContentLoaded", onDOMReady, false); function onDOMReady() { // Reload frame after getting principal from `testURI` if (!principalLoaded) { element.setAttribute("src", url); principalLoaded = true; return; } assert.equal(element.getAttribute("src"), url, "correct URL loaded"); element.removeEventListener("DOMContentLoaded", onDOMReady, false); let xrayWindow = 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; element.parentNode.removeChild(element); done(); } }; callback(helper, assert); } }; } function createWorker(assert, xrayWindow, contentScript, done) { let loader = Loader(module); let Worker = loader.require("sdk/content/worker").Worker; let worker = Worker({ 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(); }); }); // 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"; 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 = '