michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: 'use strict'; michael@0: michael@0: module.metadata = { michael@0: 'engines': { michael@0: 'Firefox': '*' michael@0: } michael@0: }; michael@0: michael@0: const { Cc, Ci } = require("chrome"); michael@0: const { Loader } = require('sdk/test/loader'); michael@0: const { LoaderWithHookedConsole } = require("sdk/test/loader"); michael@0: const timer = require("sdk/timers"); michael@0: const self = require('sdk/self'); michael@0: const { open, close, focus, ready } = require('sdk/window/helpers'); michael@0: const { isPrivate } = require('sdk/private-browsing'); michael@0: const { isWindowPBSupported, isGlobalPBSupported } = require('sdk/private-browsing/utils'); michael@0: const { defer, all } = require('sdk/core/promise'); michael@0: const { getMostRecentBrowserWindow } = require('sdk/window/utils'); michael@0: const { getWindow } = require('sdk/panel/window'); michael@0: const { pb } = require('./private-browsing/helper'); michael@0: const { URL } = require('sdk/url'); michael@0: const fixtures = require('./fixtures') michael@0: michael@0: const SVG_URL = fixtures.url('mofo_logo.SVG'); michael@0: const CSS_URL = fixtures.url('css-include-file.css'); michael@0: michael@0: const Isolate = fn => '(' + fn + ')()'; michael@0: michael@0: function ignorePassingDOMNodeWarning(type, message) { michael@0: if (type !== 'warn' || !message.startsWith('Passing a DOM node')) michael@0: console[type](message); michael@0: } michael@0: michael@0: function makeEmptyPrivateBrowserWindow(options) { michael@0: options = options || {}; michael@0: return open('chrome://browser/content/browser.xul', { michael@0: features: { michael@0: chrome: true, michael@0: toolbar: true, michael@0: private: true michael@0: } michael@0: }); michael@0: } michael@0: michael@0: exports["test Panel"] = function(assert, done) { michael@0: const { Panel } = require('sdk/panel'); michael@0: michael@0: let panel = Panel({ michael@0: contentURL: "about:buildconfig", michael@0: contentScript: "self.postMessage(1); self.on('message', function() self.postMessage(2));", michael@0: onMessage: function (message) { michael@0: assert.equal(this, panel, "The 'this' object is the panel."); michael@0: switch(message) { michael@0: case 1: michael@0: assert.pass("The panel was loaded."); michael@0: panel.postMessage(''); michael@0: break; michael@0: case 2: michael@0: assert.pass("The panel posted a message and received a response."); michael@0: panel.destroy(); michael@0: done(); michael@0: break; michael@0: } michael@0: } michael@0: }); michael@0: }; michael@0: michael@0: exports["test Panel Emit"] = function(assert, done) { michael@0: const { Panel } = require('sdk/panel'); michael@0: michael@0: let panel = Panel({ michael@0: contentURL: "about:buildconfig", michael@0: contentScript: "self.port.emit('loaded');" + michael@0: "self.port.on('addon-to-content', " + michael@0: " function() self.port.emit('received'));", michael@0: }); michael@0: panel.port.on("loaded", function () { michael@0: assert.pass("The panel was loaded and sent a first event."); michael@0: panel.port.emit("addon-to-content"); michael@0: }); michael@0: panel.port.on("received", function () { michael@0: assert.pass("The panel posted a message and received a response."); michael@0: panel.destroy(); michael@0: done(); michael@0: }); michael@0: }; michael@0: michael@0: exports["test Panel Emit Early"] = function(assert, done) { michael@0: const { Panel } = require('sdk/panel'); michael@0: michael@0: let panel = Panel({ michael@0: contentURL: "about:buildconfig", michael@0: contentScript: "self.port.on('addon-to-content', " + michael@0: " function() self.port.emit('received'));", michael@0: }); michael@0: panel.port.on("received", function () { michael@0: assert.pass("The panel posted a message early and received a response."); michael@0: panel.destroy(); michael@0: done(); michael@0: }); michael@0: panel.port.emit("addon-to-content"); michael@0: }; michael@0: michael@0: exports["test Show Hide Panel"] = function(assert, done) { michael@0: const { Panel } = require('sdk/panel'); michael@0: michael@0: let panel = Panel({ michael@0: contentScript: "self.postMessage('')", michael@0: contentScriptWhen: "end", michael@0: contentURL: "data:text/html;charset=utf-8,", michael@0: onMessage: function (message) { michael@0: panel.show(); michael@0: }, michael@0: onShow: function () { michael@0: assert.pass("The panel was shown."); michael@0: assert.equal(this, panel, "The 'this' object is the panel."); michael@0: assert.equal(this.isShowing, true, "panel.isShowing == true."); michael@0: panel.hide(); michael@0: }, michael@0: onHide: function () { michael@0: assert.pass("The panel was hidden."); michael@0: assert.equal(this, panel, "The 'this' object is the panel."); michael@0: assert.equal(this.isShowing, false, "panel.isShowing == false."); michael@0: panel.destroy(); michael@0: done(); michael@0: } michael@0: }); michael@0: }; michael@0: michael@0: exports["test Document Reload"] = function(assert, done) { michael@0: const { Panel } = require('sdk/panel'); michael@0: michael@0: let url2 = "data:text/html;charset=utf-8,page2"; michael@0: let content = michael@0: ""; michael@0: let messageCount = 0; michael@0: let panel = Panel({ michael@0: // using URL here is intentional, see bug 859009 michael@0: contentURL: URL("data:text/html;charset=utf-8," + encodeURIComponent(content)), michael@0: contentScript: "self.postMessage(window.location.href);" + michael@0: // initiate change to url2 michael@0: "self.port.once('move', function() document.defaultView.postMessage('move', '*'));", michael@0: onMessage: function (message) { michael@0: messageCount++; michael@0: assert.notEqual(message, "about:blank", "about:blank is not a message " + messageCount); michael@0: michael@0: if (messageCount == 1) { michael@0: assert.ok(/data:text\/html/.test(message), "First document had a content script; " + message); michael@0: panel.port.emit('move'); michael@0: assert.pass('move message was sent'); michael@0: return; michael@0: } michael@0: else if (messageCount == 2) { michael@0: assert.equal(message, url2, "Second document too; " + message); michael@0: panel.destroy(); michael@0: done(); michael@0: } michael@0: } michael@0: }); michael@0: assert.pass('Panel was created'); michael@0: }; michael@0: michael@0: // Test disabled because of bug 910230 michael@0: /* michael@0: exports["test Parent Resize Hack"] = function(assert, done) { michael@0: const { Panel } = require('sdk/panel'); michael@0: michael@0: let browserWindow = getMostRecentBrowserWindow(); michael@0: michael@0: let previousWidth = browserWindow.outerWidth; michael@0: let previousHeight = browserWindow.outerHeight; michael@0: michael@0: let content = "" + michael@0: "Try to resize browser window"; michael@0: michael@0: let panel = Panel({ michael@0: contentURL: "data:text/html;charset=utf-8," + encodeURIComponent(content), michael@0: contentScriptWhen: "ready", michael@0: contentScript: Isolate(() => { michael@0: self.on('message', message => { michael@0: if (message === 'resize') unsafeWindow.contentResize(); michael@0: }); michael@0: michael@0: window.addEventListener('message', ({ data }) => self.postMessage(data)); michael@0: }), michael@0: onMessage: function (message) { michael@0: if (message !== "resize-attempt") return; michael@0: michael@0: assert.equal(browserWindow, getMostRecentBrowserWindow(), michael@0: "The browser window is still the same"); michael@0: assert.equal(previousWidth, browserWindow.outerWidth, michael@0: "Size doesn't change by calling resizeTo/By/..."); michael@0: assert.equal(previousHeight, browserWindow.outerHeight, michael@0: "Size doesn't change by calling resizeTo/By/..."); michael@0: michael@0: try { michael@0: panel.destroy(); michael@0: } michael@0: catch (e) { michael@0: assert.fail(e); michael@0: throw e; michael@0: } michael@0: michael@0: done(); michael@0: }, michael@0: onShow: () => panel.postMessage('resize') michael@0: }); michael@0: michael@0: panel.show(); michael@0: } michael@0: */ michael@0: michael@0: exports["test Resize Panel"] = function(assert, done) { michael@0: const { Panel } = require('sdk/panel'); michael@0: michael@0: // These tests fail on Linux if the browser window in which the panel michael@0: // is displayed is not active. And depending on what other tests have run michael@0: // before this one, it might not be (the untitled window in which the test michael@0: // runner executes is often active). So we make sure the browser window michael@0: // is focused by focusing it before running the tests. Then, to be the best michael@0: // possible test citizen, we refocus whatever window was focused before we michael@0: // started running these tests. michael@0: michael@0: let activeWindow = Cc["@mozilla.org/embedcomp/window-watcher;1"]. michael@0: getService(Ci.nsIWindowWatcher). michael@0: activeWindow; michael@0: let browserWindow = Cc["@mozilla.org/appshell/window-mediator;1"]. michael@0: getService(Ci.nsIWindowMediator). michael@0: getMostRecentWindow("navigator:browser"); michael@0: michael@0: michael@0: function onFocus() { michael@0: browserWindow.removeEventListener("focus", onFocus, true); michael@0: michael@0: let panel = Panel({ michael@0: contentScript: "self.postMessage('')", michael@0: contentScriptWhen: "end", michael@0: contentURL: "data:text/html;charset=utf-8,", michael@0: height: 10, michael@0: width: 10, michael@0: onMessage: function (message) { michael@0: panel.show(); michael@0: }, michael@0: onShow: function () { michael@0: panel.resize(100,100); michael@0: panel.hide(); michael@0: }, michael@0: onHide: function () { michael@0: assert.ok((panel.width == 100) && (panel.height == 100), michael@0: "The panel was resized."); michael@0: if (activeWindow) michael@0: activeWindow.focus(); michael@0: done(); michael@0: } michael@0: }); michael@0: } michael@0: michael@0: if (browserWindow === activeWindow) { michael@0: onFocus(); michael@0: } michael@0: else { michael@0: browserWindow.addEventListener("focus", onFocus, true); michael@0: browserWindow.focus(); michael@0: } michael@0: }; michael@0: michael@0: exports["test Hide Before Show"] = function(assert, done) { michael@0: const { Panel } = require('sdk/panel'); michael@0: michael@0: let showCalled = false; michael@0: let panel = Panel({ michael@0: onShow: function () { michael@0: showCalled = true; michael@0: }, michael@0: onHide: function () { michael@0: assert.ok(!showCalled, 'must not emit show if was hidden before'); michael@0: done(); michael@0: } michael@0: }); michael@0: panel.show(); michael@0: panel.hide(); michael@0: }; michael@0: michael@0: exports["test Several Show Hides"] = function(assert, done) { michael@0: const { Panel } = require('sdk/panel'); michael@0: michael@0: let hideCalled = 0; michael@0: let panel = Panel({ michael@0: contentURL: "about:buildconfig", michael@0: onShow: function () { michael@0: panel.hide(); michael@0: }, michael@0: onHide: function () { michael@0: hideCalled++; michael@0: if (hideCalled < 3) michael@0: panel.show(); michael@0: else { michael@0: assert.pass("onHide called three times as expected"); michael@0: done(); michael@0: } michael@0: } michael@0: }); michael@0: panel.on('error', function(e) { michael@0: assert.fail('error was emitted:' + e.message + '\n' + e.stack); michael@0: }); michael@0: panel.show(); michael@0: }; michael@0: michael@0: exports["test Anchor And Arrow"] = function(assert, done) { michael@0: let { loader } = LoaderWithHookedConsole(module, ignorePassingDOMNodeWarning); michael@0: let { Panel } = loader.require('sdk/panel'); michael@0: michael@0: let count = 0; michael@0: let queue = []; michael@0: let tab; michael@0: michael@0: function newPanel(anchor) { michael@0: let panel = Panel({ michael@0: contentURL: "data:text/html;charset=utf-8,
Anchor: " + michael@0: anchor.id + "", michael@0: width: 200, michael@0: height: 100, michael@0: onShow: function () { michael@0: panel.destroy(); michael@0: next(); michael@0: } michael@0: }); michael@0: queue.push({ panel: panel, anchor: anchor }); michael@0: } michael@0: michael@0: function next () { michael@0: if (!queue.length) { michael@0: assert.pass("All anchored panel test displayed"); michael@0: tab.close(function () { michael@0: done(); michael@0: }); michael@0: return; michael@0: } michael@0: let { panel, anchor } = queue.shift(); michael@0: panel.show(null, anchor); michael@0: } michael@0: michael@0: let tabs= require("sdk/tabs"); michael@0: let url = 'data:text/html;charset=utf-8,' + michael@0: 'Foo
"; michael@0: let panel = Panel({ michael@0: contentURL: "data:text/html;charset=utf-8," + encodeURI(html), michael@0: contentScript: "self.port.emit('color', " + michael@0: "window.getComputedStyle(document.body.firstChild, null). " + michael@0: " getPropertyValue('color'));" michael@0: }); michael@0: panel.port.on("color", function (color) { michael@0: assert.equal(color, "rgb(255, 255, 0)", michael@0: "The panel text color style is preserved when a style exists."); michael@0: panel.destroy(); michael@0: done(); michael@0: }); michael@0: }; michael@0: michael@0: // Bug 866333 michael@0: exports["test watch event name"] = function(assert, done) { michael@0: const { Panel } = require('sdk/panel'); michael@0: michael@0: let html = "" + michael@0: "Foo
"; michael@0: michael@0: let panel = Panel({ michael@0: contentURL: "data:text/html;charset=utf-8," + encodeURI(html), michael@0: contentScript: "self.port.emit('watch', 'test');" michael@0: }); michael@0: panel.port.on("watch", function (msg) { michael@0: assert.equal(msg, "test", 'watch event name works'); michael@0: panel.destroy(); michael@0: done(); michael@0: }); michael@0: } michael@0: michael@0: // Bug 696552: Ensure panel.contentURL modification support michael@0: exports["test Change Content URL"] = function(assert, done) { michael@0: const { Panel } = require('sdk/panel'); michael@0: michael@0: let panel = Panel({ michael@0: contentURL: "about:blank", michael@0: contentScript: "self.port.emit('ready', document.location.href);" michael@0: }); michael@0: michael@0: let count = 0; michael@0: panel.port.on("ready", function (location) { michael@0: count++; michael@0: if (count == 1) { michael@0: assert.equal(location, "about:blank"); michael@0: assert.equal(panel.contentURL, "about:blank"); michael@0: panel.contentURL = "about:buildconfig"; michael@0: } michael@0: else { michael@0: assert.equal(location, "about:buildconfig"); michael@0: assert.equal(panel.contentURL, "about:buildconfig"); michael@0: panel.destroy(); michael@0: done(); michael@0: } michael@0: }); michael@0: }; michael@0: michael@0: function makeEventOrderTest(options) { michael@0: let expectedEvents = []; michael@0: michael@0: return function(assert, done) { michael@0: const { Panel } = require('sdk/panel'); michael@0: michael@0: let panel = Panel({ contentURL: "about:buildconfig" }); michael@0: michael@0: function expect(event, cb) { michael@0: expectedEvents.push(event); michael@0: panel.on(event, function() { michael@0: assert.equal(event, expectedEvents.shift()); michael@0: if (cb) michael@0: timer.setTimeout(cb, 1); michael@0: }); michael@0: return {then: expect}; michael@0: } michael@0: michael@0: options.test(assert, done, expect, panel); michael@0: } michael@0: } michael@0: michael@0: exports["test Automatic Destroy"] = function(assert) { michael@0: let loader = Loader(module); michael@0: let panel = loader.require("sdk/panel").Panel({ michael@0: contentURL: "about:buildconfig", michael@0: contentScript: michael@0: "self.port.on('event', function() self.port.emit('event-back'));" michael@0: }); michael@0: michael@0: loader.unload(); michael@0: michael@0: assert.throws(() => { michael@0: panel.port.emit("event"); michael@0: }, /already have been unloaded/, "check automatic destroy"); michael@0: }; michael@0: michael@0: exports["test Show Then Destroy"] = makeEventOrderTest({ michael@0: test: function(assert, done, expect, panel) { michael@0: panel.show(); michael@0: expect('show', function() { panel.destroy(); }). michael@0: then('hide', function() { done(); }); michael@0: } michael@0: }); michael@0: michael@0: exports["test Show Then Hide Then Destroy"] = makeEventOrderTest({ michael@0: test: function(assert, done, expect, panel) { michael@0: panel.show(); michael@0: expect('show', function() { panel.hide(); }). michael@0: then('hide', function() { panel.destroy(); done(); }); michael@0: } michael@0: }); michael@0: michael@0: exports["test Content URL Option"] = function(assert) { michael@0: const { Panel } = require('sdk/panel'); michael@0: michael@0: const URL_STRING = "about:buildconfig"; michael@0: const HTML_CONTENT = "This is a test.
"; michael@0: michael@0: let (panel = Panel({ contentURL: URL_STRING })) { michael@0: assert.pass("contentURL accepts a string URL."); michael@0: assert.equal(panel.contentURL, URL_STRING, michael@0: "contentURL is the string to which it was set."); michael@0: } michael@0: michael@0: let dataURL = "data:text/html;charset=utf-8," + encodeURIComponent(HTML_CONTENT); michael@0: let (panel = Panel({ contentURL: dataURL })) { michael@0: assert.pass("contentURL accepts a data: URL."); michael@0: } michael@0: michael@0: let (panel = Panel({})) { michael@0: assert.ok(panel.contentURL == null, michael@0: "contentURL is undefined."); michael@0: } michael@0: michael@0: assert.throws(function () Panel({ contentURL: "foo" }), michael@0: /The `contentURL` option must be a valid URL./, michael@0: "Panel throws an exception if contentURL is not a URL."); michael@0: }; michael@0: michael@0: exports["test SVG Document"] = function(assert) { michael@0: let panel = require("sdk/panel").Panel({ contentURL: SVG_URL }); michael@0: michael@0: panel.show(); michael@0: panel.hide(); michael@0: panel.destroy(); michael@0: michael@0: assert.pass("contentURL accepts a svg document"); michael@0: assert.equal(panel.contentURL, SVG_URL, michael@0: "contentURL is the string to which it was set."); michael@0: }; michael@0: michael@0: exports["test ContentScriptOptions Option"] = function(assert, done) { michael@0: let loader = Loader(module); michael@0: let panel = loader.require("sdk/panel").Panel({ michael@0: contentScript: "self.postMessage( [typeof self.options.d, self.options] );", michael@0: contentScriptWhen: "end", michael@0: contentScriptOptions: {a: true, b: [1,2,3], c: "string", d: function(){ return 'test'}}, michael@0: contentURL: "data:text/html;charset=utf-8,", michael@0: onMessage: function(msg) { michael@0: assert.equal( msg[0], 'undefined', 'functions are stripped from contentScriptOptions' ); michael@0: assert.equal( typeof msg[1], 'object', 'object as contentScriptOptions' ); michael@0: assert.equal( msg[1].a, true, 'boolean in contentScriptOptions' ); michael@0: assert.equal( msg[1].b.join(), '1,2,3', 'array and numbers in contentScriptOptions' ); michael@0: assert.equal( msg[1].c, 'string', 'string in contentScriptOptions' ); michael@0: done(); michael@0: } michael@0: }); michael@0: }; michael@0: michael@0: exports["test console.log in Panel"] = function(assert, done) { michael@0: let text = 'console.log() in Panel works!'; michael@0: let html = ''; michael@0: michael@0: let { loader } = LoaderWithHookedConsole(module, onMessage); michael@0: let { Panel } = loader.require('sdk/panel'); michael@0: michael@0: let panel = Panel({ michael@0: contentURL: 'data:text/html;charset=utf-8,' + encodeURIComponent(html) michael@0: }); michael@0: michael@0: panel.show(); michael@0: michael@0: function onMessage(type, message) { michael@0: assert.equal(type, 'log', 'console.log() works'); michael@0: assert.equal(message, text, 'console.log() works'); michael@0: panel.destroy(); michael@0: done(); michael@0: } michael@0: }; michael@0: michael@0: if (isWindowPBSupported) { michael@0: exports.testPanelDoesNotShowInPrivateWindowNoAnchor = function(assert, done) { michael@0: let { loader } = LoaderWithHookedConsole(module, ignorePassingDOMNodeWarning); michael@0: let { Panel } = loader.require("sdk/panel"); michael@0: let browserWindow = getMostRecentBrowserWindow(); michael@0: michael@0: assert.equal(isPrivate(browserWindow), false, 'open window is not private'); michael@0: michael@0: let panel = Panel({ michael@0: contentURL: SVG_URL michael@0: }); michael@0: michael@0: testShowPanel(assert, panel). michael@0: then(makeEmptyPrivateBrowserWindow). michael@0: then(focus). michael@0: then(function(window) { michael@0: assert.equal(isPrivate(window), true, 'opened window is private'); michael@0: assert.pass('private window was focused'); michael@0: return window; michael@0: }). michael@0: then(function(window) { michael@0: let { promise, resolve } = defer(); michael@0: let showTries = 0; michael@0: let showCount = 0; michael@0: michael@0: panel.on('show', function runTests() { michael@0: showCount++; michael@0: michael@0: if (showTries == 2) { michael@0: panel.removeListener('show', runTests); michael@0: assert.equal(showCount, 1, 'show count is correct - 1'); michael@0: resolve(window); michael@0: } michael@0: }); michael@0: showTries++; michael@0: panel.show(); michael@0: showTries++; michael@0: panel.show(null, browserWindow.gBrowser); michael@0: michael@0: return promise; michael@0: }). michael@0: then(function(window) { michael@0: assert.equal(panel.isShowing, true, 'panel is still showing'); michael@0: panel.hide(); michael@0: assert.equal(panel.isShowing, false, 'panel is hidden'); michael@0: return window; michael@0: }). michael@0: then(close). michael@0: then(function() { michael@0: assert.pass('private window was closed'); michael@0: }). michael@0: then(testShowPanel.bind(null, assert, panel)). michael@0: then(done, assert.fail.bind(assert)); michael@0: } michael@0: michael@0: exports.testPanelDoesNotShowInPrivateWindowWithAnchor = function(assert, done) { michael@0: let { loader } = LoaderWithHookedConsole(module, ignorePassingDOMNodeWarning); michael@0: let { Panel } = loader.require("sdk/panel"); michael@0: let browserWindow = getMostRecentBrowserWindow(); michael@0: michael@0: assert.equal(isPrivate(browserWindow), false, 'open window is not private'); michael@0: michael@0: let panel = Panel({ michael@0: contentURL: SVG_URL michael@0: }); michael@0: michael@0: testShowPanel(assert, panel). michael@0: then(makeEmptyPrivateBrowserWindow). michael@0: then(focus). michael@0: then(function(window) { michael@0: assert.equal(isPrivate(window), true, 'opened window is private'); michael@0: assert.pass('private window was focused'); michael@0: return window; michael@0: }). michael@0: then(function(window) { michael@0: let { promise, resolve } = defer(); michael@0: let showTries = 0; michael@0: let showCount = 0; michael@0: michael@0: panel.on('show', function runTests() { michael@0: showCount++; michael@0: michael@0: if (showTries == 2) { michael@0: panel.removeListener('show', runTests); michael@0: assert.equal(showCount, 1, 'show count is correct - 1'); michael@0: resolve(window); michael@0: } michael@0: }); michael@0: showTries++; michael@0: panel.show(null, window.gBrowser); michael@0: showTries++; michael@0: panel.show(null, browserWindow.gBrowser); michael@0: michael@0: return promise; michael@0: }). michael@0: then(function(window) { michael@0: assert.equal(panel.isShowing, true, 'panel is still showing'); michael@0: panel.hide(); michael@0: assert.equal(panel.isShowing, false, 'panel is hidden'); michael@0: return window; michael@0: }). michael@0: then(close). michael@0: then(function() { michael@0: assert.pass('private window was closed'); michael@0: }). michael@0: then(testShowPanel.bind(null, assert, panel)). michael@0: then(done, assert.fail.bind(assert)); michael@0: } michael@0: } michael@0: michael@0: function testShowPanel(assert, panel) { michael@0: let { promise, resolve } = defer(); michael@0: michael@0: assert.ok(!panel.isShowing, 'the panel is not showing [1]'); michael@0: michael@0: panel.once('show', function() { michael@0: assert.ok(panel.isShowing, 'the panel is showing'); michael@0: michael@0: panel.once('hide', function() { michael@0: assert.ok(!panel.isShowing, 'the panel is not showing [2]'); michael@0: michael@0: resolve(null); michael@0: }); michael@0: michael@0: panel.hide(); michael@0: }) michael@0: panel.show(); michael@0: michael@0: return promise; michael@0: } michael@0: michael@0: exports['test Style Applied Only Once'] = function (assert, done) { michael@0: let loader = Loader(module); michael@0: let panel = loader.require("sdk/panel").Panel({ michael@0: contentURL: "data:text/html;charset=utf-8,", michael@0: contentScript: michael@0: 'self.port.on("check",function() { self.port.emit("count", document.getElementsByTagName("style").length); });' + michael@0: 'self.port.on("ping", function (count) { self.port.emit("pong", count); });' michael@0: }); michael@0: michael@0: panel.port.on('count', function (styleCount) { michael@0: assert.equal(styleCount, 1, 'should only have one style'); michael@0: done(); michael@0: }); michael@0: michael@0: panel.port.on('pong', function (counter) { michael@0: panel[--counter % 2 ? 'hide' : 'show'](); michael@0: panel.port.emit(!counter ? 'check' : 'ping', counter); michael@0: }); michael@0: michael@0: panel.on('show', init); michael@0: panel.show(); michael@0: michael@0: function init () { michael@0: panel.removeListener('show', init); michael@0: panel.port.emit('ping', 10); michael@0: } michael@0: }; michael@0: michael@0: exports['test Only One Panel Open Concurrently'] = function (assert, done) { michael@0: const loader = Loader(module); michael@0: const { Panel } = loader.require('sdk/panel') michael@0: michael@0: let panelA = Panel({ michael@0: contentURL: 'about:buildconfig' michael@0: }); michael@0: michael@0: let panelB = Panel({ michael@0: contentURL: 'about:buildconfig', michael@0: onShow: function () { michael@0: // When loading two panels simulataneously, only the second michael@0: // should be shown, never showing the first michael@0: assert.equal(panelA.isShowing, false, 'First panel is hidden'); michael@0: assert.equal(panelB.isShowing, true, 'Second panel is showing'); michael@0: panelC.show(); michael@0: } michael@0: }); michael@0: michael@0: let panelC = Panel({ michael@0: contentURL: 'about:buildconfig', michael@0: onShow: function () { michael@0: assert.equal(panelA.isShowing, false, 'First panel is hidden'); michael@0: assert.equal(panelB.isShowing, false, 'Second panel is hidden'); michael@0: assert.equal(panelC.isShowing, true, 'Third panel is showing'); michael@0: done(); michael@0: } michael@0: }); michael@0: michael@0: panelA.show(); michael@0: panelB.show(); michael@0: }; michael@0: michael@0: exports['test passing DOM node as first argument'] = function (assert, done) { michael@0: let warned = defer(); michael@0: let shown = defer(); michael@0: michael@0: function onMessage(type, message) { michael@0: if (type != 'warn') return; michael@0: michael@0: let warning = 'Passing a DOM node to Panel.show() method is an unsupported ' + michael@0: 'feature that will be soon replaced. ' + michael@0: 'See: https://bugzilla.mozilla.org/show_bug.cgi?id=878877'; michael@0: michael@0: assert.equal(type, 'warn', michael@0: 'the message logged is a warning'); michael@0: michael@0: assert.equal(message, warning, michael@0: 'the warning content is correct'); michael@0: michael@0: warned.resolve(); michael@0: } michael@0: michael@0: let { loader } = LoaderWithHookedConsole(module, onMessage); michael@0: let { Panel } = loader.require('sdk/panel'); michael@0: let { Widget } = loader.require('sdk/widget'); michael@0: let { document } = getMostRecentBrowserWindow(); michael@0: let widgetId = 'widget:' + self.id + '-panel-widget'; michael@0: michael@0: let panel = Panel({ michael@0: onShow: function() { michael@0: let panelNode = document.getElementById('mainPopupSet').lastChild; michael@0: michael@0: assert.equal(panelNode.anchorNode, widgetNode, michael@0: 'the panel is properly anchored to the widget'); michael@0: michael@0: shown.resolve(); michael@0: } michael@0: }); michael@0: michael@0: let widget = Widget({ michael@0: id: 'panel-widget', michael@0: label: 'panel widget', michael@0: content: '', michael@0: }); michael@0: michael@0: let widgetNode = document.getElementById(widgetId); michael@0: michael@0: all([warned.promise, shown.promise]). michael@0: then(loader.unload). michael@0: then(done, assert.fail) michael@0: michael@0: panel.show(widgetNode); michael@0: }; michael@0: michael@0: // This test is checking that `onpupshowing` events emitted by panel's children michael@0: // are not considered. michael@0: // See Bug 886329 michael@0: exports['test nested popups'] = function (assert, done) { michael@0: let loader = Loader(module); michael@0: let { Panel } = loader.require('sdk/panel'); michael@0: let { getActiveView } = loader.require('sdk/view/core'); michael@0: let url = ''; michael@0: michael@0: let getContentWindow = panel => { michael@0: return getActiveView(panel).querySelector('iframe').contentWindow; michael@0: } michael@0: michael@0: let panel = Panel({ michael@0: contentURL: 'data:text/html;charset=utf-8,' + encodeURIComponent(url), michael@0: onShow: () => { michael@0: ready(getContentWindow(panel)).then(({ window, document }) => { michael@0: let select = document.querySelector('select'); michael@0: let event = document.createEvent('UIEvent'); michael@0: michael@0: event.initUIEvent('popupshowing', true, true, window, null); michael@0: select.dispatchEvent(event); michael@0: michael@0: assert.equal( michael@0: select, michael@0: getContentWindow(panel).document.querySelector('select'), michael@0: 'select is still loaded in panel' michael@0: ); michael@0: michael@0: done(); michael@0: }); michael@0: } michael@0: }); michael@0: michael@0: panel.show(); michael@0: }; michael@0: michael@0: exports['test emits on url changes'] = function (assert, done) { michael@0: let loader = Loader(module); michael@0: let { Panel } = loader.require('sdk/panel'); michael@0: let uriA = 'data:text/html;charset=utf-8,A'; michael@0: let uriB = 'data:text/html;charset=utf-8,B'; michael@0: michael@0: let panel = Panel({ michael@0: contentURL: uriA, michael@0: contentScript: 'new ' + function() { michael@0: self.port.on('hi', function() { michael@0: self.port.emit('bye', document.URL); michael@0: }); michael@0: } michael@0: }); michael@0: michael@0: panel.contentURL = uriB; michael@0: panel.port.emit('hi', 'hi') michael@0: panel.port.on('bye', function(uri) { michael@0: assert.equal(uri, uriB, 'message was delivered to new uri'); michael@0: loader.unload(); michael@0: done(); michael@0: }); michael@0: }; michael@0: michael@0: exports['test panel can be constructed without any arguments'] = function (assert) { michael@0: const { Panel } = require('sdk/panel'); michael@0: michael@0: let panel = Panel(); michael@0: assert.ok(true, "Creating a panel with no arguments does not throw"); michael@0: }; michael@0: michael@0: exports['test panel CSS'] = function(assert, done) { michael@0: const loader = Loader(module); michael@0: const { Panel } = loader.require('sdk/panel'); michael@0: michael@0: const { getActiveView } = loader.require('sdk/view/core'); michael@0: michael@0: const getContentWindow = panel => michael@0: getActiveView(panel).querySelector('iframe').contentWindow; michael@0: michael@0: let panel = Panel({ michael@0: contentURL: 'data:text/html;charset=utf-8,' + michael@0: '