aboutsummaryrefslogtreecommitdiff
path: root/tools/addon-sdk-1.4/packages/api-utils/tests/test-content-worker.js
diff options
context:
space:
mode:
Diffstat (limited to 'tools/addon-sdk-1.4/packages/api-utils/tests/test-content-worker.js')
-rw-r--r--tools/addon-sdk-1.4/packages/api-utils/tests/test-content-worker.js374
1 files changed, 374 insertions, 0 deletions
diff --git a/tools/addon-sdk-1.4/packages/api-utils/tests/test-content-worker.js b/tools/addon-sdk-1.4/packages/api-utils/tests/test-content-worker.js
new file mode 100644
index 0000000..ced0b60
--- /dev/null
+++ b/tools/addon-sdk-1.4/packages/api-utils/tests/test-content-worker.js
@@ -0,0 +1,374 @@
+"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);
+
+}