/* 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/. */ let { Cc, Ci } = require("chrome"); let panels = require('panel'); let tests = {}, panels, Panel; const { Loader } = require('./helpers'); tests.testPanel = function(test) { test.waitUntilDone(); let panel = Panel({ contentURL: "about:buildconfig", contentScript: "self.postMessage(1); self.on('message', function() self.postMessage(2));", onMessage: function (message) { test.assertEqual(this, panel, "The 'this' object is the panel."); switch(message) { case 1: test.pass("The panel was loaded."); panel.postMessage(''); break; case 2: test.pass("The panel posted a message and received a response."); panel.destroy(); test.done(); break; } } }); }; tests.testPanelEmit = function(test) { test.waitUntilDone(); let panel = Panel({ contentURL: "about:buildconfig", contentScript: "self.port.emit('loaded');" + "self.port.on('addon-to-content', " + " function() self.port.emit('received'));", }); panel.port.on("loaded", function () { test.pass("The panel was loaded and sent a first event."); panel.port.emit("addon-to-content"); }); panel.port.on("received", function () { test.pass("The panel posted a message and received a response."); panel.destroy(); test.done(); }); }; tests.testPanelEmitEarly = function(test) { test.waitUntilDone(); let panel = Panel({ contentURL: "about:buildconfig", contentScript: "self.port.on('addon-to-content', " + " function() self.port.emit('received'));", }); panel.port.on("received", function () { test.pass("The panel posted a message early and received a response."); panel.destroy(); test.done(); }); panel.port.emit("addon-to-content"); }; tests.testShowHidePanel = function(test) { test.waitUntilDone(); let panel = Panel({ contentScript: "self.postMessage('')", contentScriptWhen: "end", onMessage: function (message) { panel.show(); }, onShow: function () { test.pass("The panel was shown."); test.assertEqual(this, panel, "The 'this' object is the panel."); test.assertEqual(this.isShowing, true, "panel.isShowing == true."); panel.hide(); }, onHide: function () { test.pass("The panel was hidden."); test.assertEqual(this, panel, "The 'this' object is the panel."); test.assertEqual(this.isShowing, false, "panel.isShowing == false."); panel.destroy(); test.done(); } }); }; tests.testDocumentReload = function(test) { test.waitUntilDone(); let content = ""; let messageCount = 0; let panel = Panel({ contentURL: "data:text/html," + encodeURIComponent(content), contentScript: "self.postMessage(window.location.href)", onMessage: function (message) { messageCount++; if (messageCount == 1) { test.assertMatches(message, /data:text\/html,/, "First document had a content script"); } else if (messageCount == 2) { test.assertEqual(message, "about:blank", "Second document too"); panel.destroy(); test.done(); } } }); }; tests.testParentResizeHack = function(test) { let browserWindow = Cc["@mozilla.org/appshell/window-mediator;1"]. getService(Ci.nsIWindowMediator). getMostRecentWindow("navigator:browser"); let docShell = browserWindow.QueryInterface(Ci.nsIInterfaceRequestor) .getInterface(Ci.nsIWebNavigation) .QueryInterface(Ci.nsIDocShell); if (!("allowWindowControl" in docShell)) { // bug 635673 is not fixed in this firefox build test.pass("allowWindowControl attribute that allow to fix browser window " + "resize is not available on this build."); return; } test.waitUntilDone(30000); let previousWidth = browserWindow.outerWidth, previousHeight = browserWindow.outerHeight; let content = "" + "Try to resize browser window"; let panel = Panel({ contentURL: "data:text/html," + encodeURIComponent(content), contentScript: "self.on('message', function(message){" + " if (message=='resize') " + " unsafeWindow.contentResize();" + "});", contentScriptWhen: "ready", onMessage: function (message) { }, onShow: function () { panel.postMessage('resize'); require("timer").setTimeout(function () { test.assertEqual(previousWidth,browserWindow.outerWidth,"Size doesn't change by calling resizeTo/By/..."); test.assertEqual(previousHeight,browserWindow.outerHeight,"Size doesn't change by calling resizeTo/By/..."); panel.destroy(); test.done(); },0); } }); panel.show(); } tests.testResizePanel = function(test) { test.waitUntilDone(); // These tests fail on Linux if the browser window in which the panel // is displayed is not active. And depending on what other tests have run // before this one, it might not be (the untitled window in which the test // runner executes is often active). So we make sure the browser window // is focused by focusing it before running the tests. Then, to be the best // possible test citizen, we refocus whatever window was focused before we // started running these tests. let activeWindow = Cc["@mozilla.org/embedcomp/window-watcher;1"]. getService(Ci.nsIWindowWatcher). activeWindow; let browserWindow = Cc["@mozilla.org/appshell/window-mediator;1"]. getService(Ci.nsIWindowMediator). getMostRecentWindow("navigator:browser"); function onFocus() { browserWindow.removeEventListener("focus", onFocus, true); let panel = Panel({ contentScript: "self.postMessage('')", contentScriptWhen: "end", height: 10, width: 10, onMessage: function (message) { panel.show(); }, onShow: function () { panel.resize(100,100); panel.hide(); }, onHide: function () { test.assert((panel.width == 100) && (panel.height == 100), "The panel was resized."); if (activeWindow) activeWindow.focus(); test.done(); } }); } if (browserWindow === activeWindow) { onFocus(); } else { browserWindow.addEventListener("focus", onFocus, true); browserWindow.focus(); } }; tests.testHideBeforeShow = function(test) { test.waitUntilDone(); let showCalled = false; let panel = Panel({ onShow: function () { showCalled = true; }, onHide: function () { test.assert(!showCalled, 'must not emit show if was hidden before'); test.done(); } }); panel.show(); panel.hide(); }; tests.testSeveralShowHides = function(test) { test.waitUntilDone(); let hideCalled = 0; let panel = panels.Panel({ contentURL: "about:buildconfig", onShow: function () { panel.hide(); }, onHide: function () { hideCalled++; if (hideCalled < 3) panel.show(); else { test.pass("onHide called three times as expected"); test.done(); } } }); panel.on('error', function(e) { test.fail('error was emitted:' + e.message + '\n' + e.stack); }); panel.show(); }; tests.testAnchorAndArrow = function(test) { test.waitUntilDone(20000); let count = 0; function newPanel(tab, anchor) { let panel = panels.Panel({ contentURL: "data:text/html,Anchor: " + anchor.id + "", width: 200, height: 100, onShow: function () { count++; panel.destroy(); if (count==5) { test.pass("All anchored panel test displayed"); tab.close(function () { test.done(); }); } } }); panel.show(anchor); } let tabs= require("tabs"); let url = 'data:text/html,' + 'foo' + '' + '
Top Left
' + '
Top Right
' + '
Bottom Left
' + '
Bottom right
' + ''; tabs.open({ url: url, onReady: function(tab) { let browserWindow = Cc["@mozilla.org/appshell/window-mediator;1"]. getService(Ci.nsIWindowMediator). getMostRecentWindow("navigator:browser"); let window = browserWindow.content; newPanel(tab, window.document.getElementById('tl')); newPanel(tab, window.document.getElementById('tr')); newPanel(tab, window.document.getElementById('bl')); newPanel(tab, window.document.getElementById('br')); let anchor = browserWindow.document.getElementById("identity-box"); newPanel(tab, anchor); } }); }; tests.testPanelTextColor = function(test) { test.waitUntilDone(); let html = "" + "

Foo

"; let panel = Panel({ contentURL: "data:text/html," + encodeURI(html), contentScript: "self.port.emit('color', " + "window.getComputedStyle(document.body.firstChild, null). " + " getPropertyValue('color'));" }); panel.port.on("color", function (color) { test.assertEqual(color, "rgb(255, 255, 0)", "The panel text color style is preserved when a style exists."); panel.destroy(); test.done(); }); }; // Bug 696552: Ensure panel.contentURL modification support tests.testChangeContentURL = function(test) { test.waitUntilDone(); let panel = Panel({ contentURL: "about:blank", contentScript: "self.port.emit('ready', document.location.href);" }); let count = 0; panel.port.on("ready", function (location) { count++; if (count == 1) { test.assertEqual(location, "about:blank"); test.assertEqual(panel.contentURL, "about:blank"); panel.contentURL = "about:buildconfig"; } else { test.assertEqual(location, "about:buildconfig"); test.assertEqual(panel.contentURL, "about:buildconfig"); panel.destroy(); test.done(); } }); }; function makeEventOrderTest(options) { let expectedEvents = []; return function(test) { let panel = panels.Panel({ contentURL: "about:buildconfig" }); function expect(event, cb) { expectedEvents.push(event); panel.on(event, function() { test.assertEqual(event, expectedEvents.shift()); if (cb) require("timer").setTimeout(cb, 1); }); return {then: expect}; } test.waitUntilDone(); options.test(test, expect, panel); } } tests.testAutomaticDestroy = function(test) { let loader = Loader(module); let panel = loader.require("panel").Panel({ contentURL: "about:buildconfig", contentScript: "self.port.on('event', function() self.port.emit('event-back'));" }); loader.unload(); panel.port.on("event-back", function () { test.fail("Panel should have been destroyed on module unload"); }); panel.port.emit("event"); test.pass("check automatic destroy"); }; tests.testWaitForInitThenShowThenDestroy = makeEventOrderTest({ test: function(test, expect, panel) { expect('inited', function() { panel.show(); }). then('show', function() { panel.destroy(); }). then('hide', function() { test.done(); }); } }); tests.testShowThenWaitForInitThenDestroy = makeEventOrderTest({ test: function(test, expect, panel) { panel.show(); expect('inited'). then('show', function() { panel.destroy(); }). then('hide', function() { test.done(); }); } }); tests.testShowThenHideThenDestroy = makeEventOrderTest({ test: function(test, expect, panel) { panel.show(); expect('show', function() { panel.hide(); }). then('hide', function() { panel.destroy(); test.done(); }); } }); tests.testContentURLOption = function(test) { const URL_STRING = "about:buildconfig"; const HTML_CONTENT = "Test

This is a test.

"; let (panel = Panel({ contentURL: URL_STRING })) { test.pass("contentURL accepts a string URL."); test.assertEqual(panel.contentURL, URL_STRING, "contentURL is the string to which it was set."); } let dataURL = "data:text/html," + encodeURIComponent(HTML_CONTENT); let (panel = Panel({ contentURL: dataURL })) { test.pass("contentURL accepts a data: URL."); } let (panel = Panel({})) { test.assert(panel.contentURL == null, "contentURL is undefined."); } test.assertRaises(function () Panel({ contentURL: "foo" }), "The `contentURL` option must be a valid URL.", "Panel throws an exception if contentURL is not a URL."); }; let panelSupported = true; try { panels = require("panel"); Panel = panels.Panel; } catch(ex if ex.message == [ "The panel module currently supports only Firefox. In the future ", "we would like it to support other applications, however. Please see ", "https://bugzilla.mozilla.org/show_bug.cgi?id=jetpack-panel-apps ", "for more information." ].join("")) { panelSupported = false; } if (panelSupported) { for (let test in tests) exports[test] = tests[test]; } else { exports.testPanelNotSupported = function(test) { test.pass("The panel module is not supported on this app."); } }