diff options
Diffstat (limited to 'tools/addon-sdk-1.5/packages/api-utils/tests/test-content-worker.js')
-rw-r--r-- | tools/addon-sdk-1.5/packages/api-utils/tests/test-content-worker.js | 378 |
1 files changed, 378 insertions, 0 deletions
diff --git a/tools/addon-sdk-1.5/packages/api-utils/tests/test-content-worker.js b/tools/addon-sdk-1.5/packages/api-utils/tests/test-content-worker.js new file mode 100644 index 0000000..b8de9f0 --- /dev/null +++ b/tools/addon-sdk-1.5/packages/api-utils/tests/test-content-worker.js @@ -0,0 +1,378 @@ +/* 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/. */ + +"use stirct"; + +const { Cc, Ci } = require('chrome'); +const timer = require('timer'); + +function makeWindow(contentURL) { + let content = + '<?xml version="1.0"?>' + + '<window ' + + 'xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">' + + '<iframe id="content" type="content" src="' + + encodeURIComponent(contentURL) + '"/>' + + '<script>var documentValue=true;</script>' + + '</window>'; + var url = "data:application/vnd.mozilla.xul+xml," + + encodeURIComponent(content); + var features = ["chrome", "width=10", "height=10"]; + + return Cc["@mozilla.org/embedcomp/window-watcher;1"]. + getService(Ci.nsIWindowWatcher). + openWindow(null, url, null, features.join(","), null); +} + +const { Worker } = require('content/worker'); +exports['test:sample'] = function(test) { + let window = makeWindow(); + test.waitUntilDone(); + + // As window has just being created, its document is still loading, + // and we have about:blank document before the expected one + test.assertEqual(window.document.location.href, "about:blank", + "window starts by loading about:blank"); + + // We need to wait for the load/unload of temporary about:blank + // or our worker is going to be automatically destroyed + window.addEventListener("load", function onload() { + window.removeEventListener("load", onload, true); + + test.assertNotEqual(window.document.location.href, "about:blank", + "window is now on the right document"); + + let worker = Worker({ + window: window, + contentScript: 'new ' + function WorkerScope() { + // window is accessible + let myLocation = window.location.toString(); + self.on('message', function(data) { + if (data == 'hi!') + self.postMessage('bye!'); + }); + }, + contentScriptWhen: 'ready', + onMessage: function(msg) { + test.assertEqual('bye!', msg); + test.assertEqual(worker.url, window.document.location.href, + "worker.url still works"); + test.done(); + } + }); + + test.assertEqual(worker.url, window.document.location.href, + "worker.url works"); + worker.postMessage('hi!'); + + }, true); + +} + +exports['test:emit'] = function(test) { + let window = makeWindow(); + test.waitUntilDone(); + + let worker = Worker({ + window: window, + contentScript: 'new ' + function WorkerScope() { + // Validate self.on and self.emit + self.port.on('addon-to-content', function (data) { + self.port.emit('content-to-addon', data); + }); + + // Check for global pollution + //if (typeof on != "undefined") + // self.postMessage("`on` is in globals"); + if (typeof once != "undefined") + self.postMessage("`once` is in globals"); + if (typeof emit != "undefined") + self.postMessage("`emit` is in globals"); + + }, + onMessage: function(msg) { + test.fail("Got an unexpected message : "+msg); + } + }); + + // Validate worker.port + worker.port.on('content-to-addon', function (data) { + test.assertEqual(data, "event data"); + test.done(); + }); + worker.port.emit('addon-to-content', 'event data'); + +} + +exports['test:emit hack message'] = function(test) { + let window = makeWindow(); + test.waitUntilDone(); + + let worker = Worker({ + window: window, + contentScript: 'new ' + function WorkerScope() { + // Validate self.port + self.port.on('message', function (data) { + self.port.emit('message', data); + }); + // We should not receive message on self, but only on self.port + self.on('message', function (data) { + self.postMessage('message', data); + }); + }, + onError: function(e) { + test.fail("Got exception: "+e); + } + }); + + worker.port.on('message', function (data) { + test.assertEqual(data, "event data"); + test.done(); + }); + worker.on('message', function (data) { + test.fail("Got an unexpected message : "+msg); + }); + worker.port.emit('message', 'event data'); + +} + +exports['test:n-arguments emit'] = function(test) { + let window = makeWindow(); + test.waitUntilDone(); + + let worker = Worker({ + window: window, + contentScript: 'new ' + function WorkerScope() { + // Validate self.on and self.emit + self.port.on('addon-to-content', function (a1, a2, a3) { + self.port.emit('content-to-addon', a1, a2, a3); + }); + } + }); + + // Validate worker.port + worker.port.on('content-to-addon', function (arg1, arg2, arg3) { + test.assertEqual(arg1, "first argument"); + test.assertEqual(arg2, "second"); + test.assertEqual(arg3, "third"); + test.done(); + }); + worker.port.emit('addon-to-content', 'first argument', 'second', 'third'); +} + +exports['test:post-json-values-only'] = function(test) { + let window = makeWindow("data:text/html,"); + test.waitUntilDone(); + + window.addEventListener("load", function onload() { + window.removeEventListener("load", onload, true); + + let worker = Worker({ + window: window.document.getElementById("content").contentWindow, + contentScript: 'new ' + function WorkerScope() { + self.on('message', function (message) { + self.postMessage([ message.fun === undefined, + typeof message.w, + message.w && "port" in message.w, + message.w.url, + Array.isArray(message.array), + JSON.stringify(message.array)]); + }); + } + }); + + // Validate worker.onMessage + let array = [1, 2, 3]; + worker.on('message', function (message) { + test.assert(message[0], "function becomes undefined"); + test.assertEqual(message[1], "object", "object stays object"); + test.assert(message[2], "object's attributes are enumerable"); + test.assertEqual(message[3], "about:blank", "jsonable attributes are accessible"); + // See bug 714891, Arrays may be broken over compartements: + test.assert(message[4], "Array keeps being an array"); + test.assertEqual(message[5], JSON.stringify(array), + "Array is correctly serialized"); + test.done(); + }); + worker.postMessage({ fun: function () {}, w: worker, array: array }); + + }, true); + +}; + +exports['test:emit-json-values-only'] = function(test) { + let window = makeWindow("data:text/html,"); + test.waitUntilDone(); + + window.addEventListener("load", function onload() { + window.removeEventListener("load", onload, true); + + let win = window.document.getElementById("content").contentWindow; + let worker = Worker({ + window: win, + contentScript: 'new ' + function WorkerScope() { + // Validate self.on and self.emit + self.port.on('addon-to-content', function (fun, w, obj, array) { + self.port.emit('content-to-addon', [ + fun === null, + typeof w, + "port" in w, + w.url, + "fun" in obj, + Object.keys(obj.dom).length, + Array.isArray(array), + JSON.stringify(array) + ]); + }); + } + }); + + // Validate worker.port + let array = [1, 2, 3]; + worker.port.on('content-to-addon', function (result) { + test.assert(result[0], "functions become null"); + test.assertEqual(result[1], "object", "objects stay objects"); + test.assert(result[2], "object's attributes are enumerable"); + test.assertEqual(result[3], "about:blank", "json attribute is accessible"); + test.assert(!result[4], "function as object attribute is removed"); + test.assertEqual(result[5], 0, "DOM nodes are converted into empty object"); + // See bug 714891, Arrays may be broken over compartements: + test.assert(result[6], "Array keeps being an array"); + test.assertEqual(result[7], JSON.stringify(array), + "Array is correctly serialized"); + test.done(); + }); + let obj = { + fun: function () {}, + dom: win.document.documentElement + }; + worker.port.emit('addon-to-content', function () {}, worker, obj, array); + + }, true); + +} + +exports['test:content is wrapped'] = function(test) { + let contentURL = 'data:text/html,<script>var documentValue=true;</script>'; + let window = makeWindow(contentURL); + test.waitUntilDone(); + + window.addEventListener("load", function onload() { + window.removeEventListener("load", onload, true); + + let worker = Worker({ + window: window.document.getElementById("content").contentWindow, + contentScript: 'new ' + function WorkerScope() { + self.postMessage(!window.documentValue); + }, + contentScriptWhen: 'ready', + onMessage: function(msg) { + test.assert(msg, + "content script has a wrapped access to content document"); + test.done(); + } + }); + + }, true); + +} + +exports['test:chrome is unwrapped'] = function(test) { + let window = makeWindow(); + test.waitUntilDone(); + + window.addEventListener("load", function onload() { + window.removeEventListener("load", onload, true); + + let worker = Worker({ + window: window, + contentScript: 'new ' + function WorkerScope() { + self.postMessage(window.documentValue); + }, + contentScriptWhen: 'ready', + onMessage: function(msg) { + test.assert(msg, + "content script has an unwrapped access to chrome document"); + test.done(); + } + }); + + }, true); + +} + +exports['test:setTimeout can\'t be cancelled by content'] = function(test) { + let contentURL = 'data:text/html,<script>var documentValue=true;</script>'; + let window = makeWindow(contentURL); + test.waitUntilDone(); + + window.addEventListener("load", function onload() { + window.removeEventListener("load", onload, true); + + let worker = Worker({ + window: window.document.getElementById("content").contentWindow, + contentScript: 'new ' + function WorkerScope() { + let id = setTimeout(function () { + self.postMessage("timeout"); + }, 100); + unsafeWindow.eval("clearTimeout("+id+");"); + }, + contentScriptWhen: 'ready', + onMessage: function(msg) { + test.assert(msg, + "content didn't managed to cancel our setTimeout"); + test.done(); + } + }); + + }, true); + +} + +exports['test:setTimeout are unregistered on content unload'] = function(test) { + let contentURL = 'data:text/html,foo'; + let window = makeWindow(contentURL); + test.waitUntilDone(); + + window.addEventListener("load", function onload() { + window.removeEventListener("load", onload, true); + + let iframe = window.document.getElementById("content"); + let originalDocument = iframe.contentDocument; + let worker = Worker({ + window: iframe.contentWindow, + contentScript: 'new ' + function WorkerScope() { + document.title = "ok"; + let i = 0; + setInterval(function () { + document.title = i++; + }, 10); + }, + contentScriptWhen: 'ready' + }); + + // Change location so that content script is destroyed, + // and all setTimeout/setInterval should be unregistered. + // Wait some cycles in order to execute some intervals. + timer.setTimeout(function () { + // Bug 689621: Wait for the new document load so that we are sure that + // previous document cancelled its intervals + iframe.addEventListener("load", function onload() { + iframe.removeEventListener("load", onload, true); + let titleAfterLoad = originalDocument.title; + // Wait additional cycles to verify that intervals are really cancelled + timer.setTimeout(function () { + test.assertEqual(iframe.contentDocument.title, "final", + "New document has not been modified"); + test.assertEqual(originalDocument.title, titleAfterLoad, + "Nor previous one"); + test.done(); + }, 100); + }, true); + iframe.setAttribute("src", "data:text/html,<title>final</title>"); + }, 100); + + }, true); + +} |