addon-sdk/source/test/test-panel.js

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     4 'use strict';
     6 module.metadata = {
     7   'engines': {
     8     'Firefox': '*'
     9   }
    10 };
    12 const { Cc, Ci } = require("chrome");
    13 const { Loader } = require('sdk/test/loader');
    14 const { LoaderWithHookedConsole } = require("sdk/test/loader");
    15 const timer = require("sdk/timers");
    16 const self = require('sdk/self');
    17 const { open, close, focus, ready } = require('sdk/window/helpers');
    18 const { isPrivate } = require('sdk/private-browsing');
    19 const { isWindowPBSupported, isGlobalPBSupported } = require('sdk/private-browsing/utils');
    20 const { defer, all } = require('sdk/core/promise');
    21 const { getMostRecentBrowserWindow } = require('sdk/window/utils');
    22 const { getWindow } = require('sdk/panel/window');
    23 const { pb } = require('./private-browsing/helper');
    24 const { URL } = require('sdk/url');
    25 const fixtures = require('./fixtures')
    27 const SVG_URL = fixtures.url('mofo_logo.SVG');
    28 const CSS_URL = fixtures.url('css-include-file.css');
    30 const Isolate = fn => '(' + fn + ')()';
    32 function ignorePassingDOMNodeWarning(type, message) {
    33   if (type !== 'warn' || !message.startsWith('Passing a DOM node'))
    34     console[type](message);
    35 }
    37 function makeEmptyPrivateBrowserWindow(options) {
    38   options = options || {};
    39   return open('chrome://browser/content/browser.xul', {
    40     features: {
    41       chrome: true,
    42       toolbar: true,
    43       private: true
    44     }
    45   });
    46 }
    48 exports["test Panel"] = function(assert, done) {
    49   const { Panel } = require('sdk/panel');
    51   let panel = Panel({
    52     contentURL: "about:buildconfig",
    53     contentScript: "self.postMessage(1); self.on('message', function() self.postMessage(2));",
    54     onMessage: function (message) {
    55       assert.equal(this, panel, "The 'this' object is the panel.");
    56       switch(message) {
    57         case 1:
    58           assert.pass("The panel was loaded.");
    59           panel.postMessage('');
    60           break;
    61         case 2:
    62           assert.pass("The panel posted a message and received a response.");
    63           panel.destroy();
    64           done();
    65           break;
    66       }
    67     }
    68   });
    69 };
    71 exports["test Panel Emit"] = function(assert, done) {
    72   const { Panel } = require('sdk/panel');
    74   let panel = Panel({
    75     contentURL: "about:buildconfig",
    76     contentScript: "self.port.emit('loaded');" +
    77                    "self.port.on('addon-to-content', " +
    78                    "             function() self.port.emit('received'));",
    79   });
    80   panel.port.on("loaded", function () {
    81     assert.pass("The panel was loaded and sent a first event.");
    82     panel.port.emit("addon-to-content");
    83   });
    84   panel.port.on("received", function () {
    85     assert.pass("The panel posted a message and received a response.");
    86     panel.destroy();
    87     done();
    88   });
    89 };
    91 exports["test Panel Emit Early"] = function(assert, done) {
    92   const { Panel } = require('sdk/panel');
    94   let panel = Panel({
    95     contentURL: "about:buildconfig",
    96     contentScript: "self.port.on('addon-to-content', " +
    97                    "             function() self.port.emit('received'));",
    98   });
    99   panel.port.on("received", function () {
   100     assert.pass("The panel posted a message early and received a response.");
   101     panel.destroy();
   102     done();
   103   });
   104   panel.port.emit("addon-to-content");
   105 };
   107 exports["test Show Hide Panel"] = function(assert, done) {
   108   const { Panel } = require('sdk/panel');
   110   let panel = Panel({
   111     contentScript: "self.postMessage('')",
   112     contentScriptWhen: "end",
   113     contentURL: "data:text/html;charset=utf-8,",
   114     onMessage: function (message) {
   115       panel.show();
   116     },
   117     onShow: function () {
   118       assert.pass("The panel was shown.");
   119       assert.equal(this, panel, "The 'this' object is the panel.");
   120       assert.equal(this.isShowing, true, "panel.isShowing == true.");
   121       panel.hide();
   122     },
   123     onHide: function () {
   124       assert.pass("The panel was hidden.");
   125       assert.equal(this, panel, "The 'this' object is the panel.");
   126       assert.equal(this.isShowing, false, "panel.isShowing == false.");
   127       panel.destroy();
   128       done();
   129     }
   130   });
   131 };
   133 exports["test Document Reload"] = function(assert, done) {
   134   const { Panel } = require('sdk/panel');
   136   let url2 = "data:text/html;charset=utf-8,page2";
   137   let content =
   138     "<script>" +
   139     "window.addEventListener('message', function({ data }) {"+
   140     "  if (data == 'move') window.location = '" + url2 + "';" +
   141     '}, false);' +
   142     "</script>";
   143   let messageCount = 0;
   144   let panel = Panel({
   145     // using URL here is intentional, see bug 859009
   146     contentURL: URL("data:text/html;charset=utf-8," + encodeURIComponent(content)),
   147     contentScript: "self.postMessage(window.location.href);" +
   148                    // initiate change to url2
   149                    "self.port.once('move', function() document.defaultView.postMessage('move', '*'));",
   150     onMessage: function (message) {
   151       messageCount++;
   152       assert.notEqual(message, "about:blank", "about:blank is not a message " + messageCount);
   154       if (messageCount == 1) {
   155         assert.ok(/data:text\/html/.test(message), "First document had a content script; " + message);
   156         panel.port.emit('move');
   157         assert.pass('move message was sent');
   158         return;
   159       }
   160       else if (messageCount == 2) {
   161         assert.equal(message, url2, "Second document too; " + message);
   162         panel.destroy();
   163         done();
   164       }
   165     }
   166   });
   167   assert.pass('Panel was created');
   168 };
   170 // Test disabled because of bug 910230
   171 /*
   172 exports["test Parent Resize Hack"] = function(assert, done) {
   173   const { Panel } = require('sdk/panel');
   175   let browserWindow = getMostRecentBrowserWindow();
   177   let previousWidth = browserWindow.outerWidth;
   178   let previousHeight = browserWindow.outerHeight;
   180   let content = "<script>" +
   181                 "function contentResize() {" +
   182                 "  resizeTo(200,200);" +
   183                 "  resizeBy(200,200);" +
   184                 "  window.postMessage('resize-attempt', '*');" +
   185                 "}" +
   186                 "</script>" +
   187                 "Try to resize browser window";
   189   let panel = Panel({
   190     contentURL: "data:text/html;charset=utf-8," + encodeURIComponent(content),
   191     contentScriptWhen: "ready",
   192     contentScript: Isolate(() => {
   193         self.on('message', message => {
   194           if (message === 'resize') unsafeWindow.contentResize();
   195         });
   197         window.addEventListener('message', ({ data }) => self.postMessage(data));
   198       }),
   199     onMessage: function (message) {
   200       if (message !== "resize-attempt") return;
   202       assert.equal(browserWindow, getMostRecentBrowserWindow(),
   203         "The browser window is still the same");
   204       assert.equal(previousWidth, browserWindow.outerWidth,
   205         "Size doesn't change by calling resizeTo/By/...");
   206       assert.equal(previousHeight, browserWindow.outerHeight,
   207         "Size doesn't change by calling resizeTo/By/...");
   209       try {
   210         panel.destroy();
   211       }
   212       catch (e) {
   213         assert.fail(e);
   214         throw e;
   215       }
   217       done();
   218     },
   219     onShow: () => panel.postMessage('resize')
   220   });
   222   panel.show();
   223 }
   224 */
   226 exports["test Resize Panel"] = function(assert, done) {
   227   const { Panel } = require('sdk/panel');
   229   // These tests fail on Linux if the browser window in which the panel
   230   // is displayed is not active.  And depending on what other tests have run
   231   // before this one, it might not be (the untitled window in which the test
   232   // runner executes is often active).  So we make sure the browser window
   233   // is focused by focusing it before running the tests.  Then, to be the best
   234   // possible test citizen, we refocus whatever window was focused before we
   235   // started running these tests.
   237   let activeWindow = Cc["@mozilla.org/embedcomp/window-watcher;1"].
   238                       getService(Ci.nsIWindowWatcher).
   239                       activeWindow;
   240   let browserWindow = Cc["@mozilla.org/appshell/window-mediator;1"].
   241                       getService(Ci.nsIWindowMediator).
   242                       getMostRecentWindow("navigator:browser");
   245   function onFocus() {
   246     browserWindow.removeEventListener("focus", onFocus, true);
   248     let panel = Panel({
   249       contentScript: "self.postMessage('')",
   250       contentScriptWhen: "end",
   251       contentURL: "data:text/html;charset=utf-8,",
   252       height: 10,
   253       width: 10,
   254       onMessage: function (message) {
   255         panel.show();
   256       },
   257       onShow: function () {
   258         panel.resize(100,100);
   259         panel.hide();
   260       },
   261       onHide: function () {
   262         assert.ok((panel.width == 100) && (panel.height == 100),
   263           "The panel was resized.");
   264         if (activeWindow)
   265           activeWindow.focus();
   266         done();
   267       }
   268     });
   269   }
   271   if (browserWindow === activeWindow) {
   272     onFocus();
   273   }
   274   else {
   275     browserWindow.addEventListener("focus", onFocus, true);
   276     browserWindow.focus();
   277   }
   278 };
   280 exports["test Hide Before Show"] = function(assert, done) {
   281   const { Panel } = require('sdk/panel');
   283   let showCalled = false;
   284   let panel = Panel({
   285     onShow: function () {
   286       showCalled = true;
   287     },
   288     onHide: function () {
   289       assert.ok(!showCalled, 'must not emit show if was hidden before');
   290       done();
   291     }
   292   });
   293   panel.show();
   294   panel.hide();
   295 };
   297 exports["test Several Show Hides"] = function(assert, done) {
   298   const { Panel } = require('sdk/panel');
   300   let hideCalled = 0;
   301   let panel = Panel({
   302     contentURL: "about:buildconfig",
   303     onShow: function () {
   304       panel.hide();
   305     },
   306     onHide: function () {
   307       hideCalled++;
   308       if (hideCalled < 3)
   309         panel.show();
   310       else {
   311         assert.pass("onHide called three times as expected");
   312         done();
   313       }
   314     }
   315   });
   316   panel.on('error', function(e) {
   317     assert.fail('error was emitted:' + e.message + '\n' + e.stack);
   318   });
   319   panel.show();
   320 };
   322 exports["test Anchor And Arrow"] = function(assert, done) {
   323   let { loader } = LoaderWithHookedConsole(module, ignorePassingDOMNodeWarning);
   324   let { Panel } = loader.require('sdk/panel');
   326   let count = 0;
   327   let queue = [];
   328   let tab;
   330   function newPanel(anchor) {
   331     let panel = Panel({
   332       contentURL: "data:text/html;charset=utf-8,<html><body style='padding: 0; margin: 0; " +
   333                   "background: gray; text-align: center;'>Anchor: " +
   334                   anchor.id + "</body></html>",
   335       width: 200,
   336       height: 100,
   337       onShow: function () {
   338         panel.destroy();
   339         next();
   340       }
   341     });
   342     queue.push({ panel: panel, anchor: anchor });
   343   }
   345   function next () {
   346     if (!queue.length) {
   347       assert.pass("All anchored panel test displayed");
   348       tab.close(function () {
   349         done();
   350       });
   351       return;
   352     }
   353     let { panel, anchor } = queue.shift();
   354     panel.show(null, anchor);
   355   }
   357   let tabs= require("sdk/tabs");
   358   let url = 'data:text/html;charset=utf-8,' +
   359     '<html><head><title>foo</title></head><body>' +
   360     '<style>div {background: gray; position: absolute; width: 300px; ' +
   361            'border: 2px solid black;}</style>' +
   362     '<div id="tl" style="top: 0px; left: 0px;">Top Left</div>' +
   363     '<div id="tr" style="top: 0px; right: 0px;">Top Right</div>' +
   364     '<div id="bl" style="bottom: 0px; left: 0px;">Bottom Left</div>' +
   365     '<div id="br" style="bottom: 0px; right: 0px;">Bottom right</div>' +
   366     '</body></html>';
   368   tabs.open({
   369     url: url,
   370     onReady: function(_tab) {
   371       tab = _tab;
   372       let browserWindow = Cc["@mozilla.org/appshell/window-mediator;1"].
   373                       getService(Ci.nsIWindowMediator).
   374                       getMostRecentWindow("navigator:browser");
   375       let window = browserWindow.content;
   376       newPanel(window.document.getElementById('tl'));
   377       newPanel(window.document.getElementById('tr'));
   378       newPanel(window.document.getElementById('bl'));
   379       newPanel(window.document.getElementById('br'));
   380       let anchor = browserWindow.document.getElementById("identity-box");
   381       newPanel(anchor);
   383       next();
   384     }
   385   });
   386 };
   388 exports["test Panel Focus True"] = function(assert, done) {
   389   const { Panel } = require('sdk/panel');
   391   const FM = Cc["@mozilla.org/focus-manager;1"].
   392                 getService(Ci.nsIFocusManager);
   394   let browserWindow = Cc["@mozilla.org/appshell/window-mediator;1"].
   395                       getService(Ci.nsIWindowMediator).
   396                       getMostRecentWindow("navigator:browser");
   398   // Make sure there is a focused element
   399   browserWindow.document.documentElement.focus();
   401   // Get the current focused element
   402   let focusedElement = FM.focusedElement;
   404   let panel = Panel({
   405     contentURL: "about:buildconfig",
   406     focus: true,
   407     onShow: function () {
   408       assert.ok(focusedElement !== FM.focusedElement,
   409         "The panel takes the focus away.");
   410       done();
   411     }
   412   });
   413   panel.show();
   414 };
   416 exports["test Panel Focus False"] = function(assert, done) {
   417   const { Panel } = require('sdk/panel');
   419   const FM = Cc["@mozilla.org/focus-manager;1"].
   420                 getService(Ci.nsIFocusManager);
   422   let browserWindow = Cc["@mozilla.org/appshell/window-mediator;1"].
   423                       getService(Ci.nsIWindowMediator).
   424                       getMostRecentWindow("navigator:browser");
   426   // Make sure there is a focused element
   427   browserWindow.document.documentElement.focus();
   429   // Get the current focused element
   430   let focusedElement = FM.focusedElement;
   432   let panel = Panel({
   433     contentURL: "about:buildconfig",
   434     focus: false,
   435     onShow: function () {
   436       assert.ok(focusedElement === FM.focusedElement,
   437         "The panel does not take the focus away.");
   438       done();
   439     }
   440   });
   441   panel.show();
   442 };
   444 exports["test Panel Focus Not Set"] = function(assert, done) {
   445   const { Panel } = require('sdk/panel');
   447   const FM = Cc["@mozilla.org/focus-manager;1"].
   448                 getService(Ci.nsIFocusManager);
   450   let browserWindow = Cc["@mozilla.org/appshell/window-mediator;1"].
   451                       getService(Ci.nsIWindowMediator).
   452                       getMostRecentWindow("navigator:browser");
   454   // Make sure there is a focused element
   455   browserWindow.document.documentElement.focus();
   457   // Get the current focused element
   458   let focusedElement = FM.focusedElement;
   460   let panel = Panel({
   461     contentURL: "about:buildconfig",
   462     onShow: function () {
   463       assert.ok(focusedElement !== FM.focusedElement,
   464         "The panel takes the focus away.");
   465       done();
   466     }
   467   });
   468   panel.show();
   469 };
   471 exports["test Panel Text Color"] = function(assert, done) {
   472   const { Panel } = require('sdk/panel');
   474   let html = "<html><head><style>body {color: yellow}</style></head>" +
   475              "<body><p>Foo</p></body></html>";
   476   let panel = Panel({
   477     contentURL: "data:text/html;charset=utf-8," + encodeURI(html),
   478     contentScript: "self.port.emit('color', " +
   479                    "window.getComputedStyle(document.body.firstChild, null). " +
   480                    "       getPropertyValue('color'));"
   481   });
   482   panel.port.on("color", function (color) {
   483     assert.equal(color, "rgb(255, 255, 0)",
   484       "The panel text color style is preserved when a style exists.");
   485     panel.destroy();
   486     done();
   487   });
   488 };
   490 // Bug 866333
   491 exports["test watch event name"] = function(assert, done) {
   492   const { Panel } = require('sdk/panel');
   494   let html = "<html><head><style>body {color: yellow}</style></head>" +
   495              "<body><p>Foo</p></body></html>";
   497   let panel = Panel({
   498     contentURL: "data:text/html;charset=utf-8," + encodeURI(html),
   499     contentScript: "self.port.emit('watch', 'test');"
   500   });
   501   panel.port.on("watch", function (msg) {
   502     assert.equal(msg, "test", 'watch event name works');
   503     panel.destroy();
   504     done();
   505   });
   506 }
   508 // Bug 696552: Ensure panel.contentURL modification support
   509 exports["test Change Content URL"] = function(assert, done) {
   510   const { Panel } = require('sdk/panel');
   512   let panel = Panel({
   513     contentURL: "about:blank",
   514     contentScript: "self.port.emit('ready', document.location.href);"
   515   });
   517   let count = 0;
   518   panel.port.on("ready", function (location) {
   519     count++;
   520     if (count == 1) {
   521       assert.equal(location, "about:blank");
   522       assert.equal(panel.contentURL, "about:blank");
   523       panel.contentURL = "about:buildconfig";
   524     }
   525     else {
   526       assert.equal(location, "about:buildconfig");
   527       assert.equal(panel.contentURL, "about:buildconfig");
   528       panel.destroy();
   529       done();
   530     }
   531   });
   532 };
   534 function makeEventOrderTest(options) {
   535   let expectedEvents = [];
   537   return function(assert, done) {
   538     const { Panel } = require('sdk/panel');
   540     let panel = Panel({ contentURL: "about:buildconfig" });
   542     function expect(event, cb) {
   543       expectedEvents.push(event);
   544       panel.on(event, function() {
   545         assert.equal(event, expectedEvents.shift());
   546         if (cb)
   547           timer.setTimeout(cb, 1);
   548       });
   549       return {then: expect};
   550     }
   552     options.test(assert, done, expect, panel);
   553   }
   554 }
   556 exports["test Automatic Destroy"] = function(assert) {
   557   let loader = Loader(module);
   558   let panel = loader.require("sdk/panel").Panel({
   559     contentURL: "about:buildconfig",
   560     contentScript:
   561       "self.port.on('event', function() self.port.emit('event-back'));"
   562   });
   564   loader.unload();
   566   assert.throws(() => {
   567     panel.port.emit("event");
   568   }, /already have been unloaded/, "check automatic destroy");
   569 };
   571 exports["test Show Then Destroy"] = makeEventOrderTest({
   572   test: function(assert, done, expect, panel) {
   573     panel.show();
   574     expect('show', function() { panel.destroy(); }).
   575       then('hide', function() { done(); });
   576   }
   577 });
   579 exports["test Show Then Hide Then Destroy"] = makeEventOrderTest({
   580   test: function(assert, done, expect, panel) {
   581     panel.show();
   582     expect('show', function() { panel.hide(); }).
   583       then('hide', function() { panel.destroy(); done(); });
   584   }
   585 });
   587 exports["test Content URL Option"] = function(assert) {
   588   const { Panel } = require('sdk/panel');
   590   const URL_STRING = "about:buildconfig";
   591   const HTML_CONTENT = "<html><title>Test</title><p>This is a test.</p></html>";
   593   let (panel = Panel({ contentURL: URL_STRING })) {
   594     assert.pass("contentURL accepts a string URL.");
   595     assert.equal(panel.contentURL, URL_STRING,
   596                 "contentURL is the string to which it was set.");
   597   }
   599   let dataURL = "data:text/html;charset=utf-8," + encodeURIComponent(HTML_CONTENT);
   600   let (panel = Panel({ contentURL: dataURL })) {
   601     assert.pass("contentURL accepts a data: URL.");
   602   }
   604   let (panel = Panel({})) {
   605     assert.ok(panel.contentURL == null,
   606                 "contentURL is undefined.");
   607   }
   609   assert.throws(function () Panel({ contentURL: "foo" }),
   610                     /The `contentURL` option must be a valid URL./,
   611                     "Panel throws an exception if contentURL is not a URL.");
   612 };
   614 exports["test SVG Document"] = function(assert) {
   615   let panel = require("sdk/panel").Panel({ contentURL: SVG_URL });
   617   panel.show();
   618   panel.hide();
   619   panel.destroy();
   621   assert.pass("contentURL accepts a svg document");
   622   assert.equal(panel.contentURL, SVG_URL,
   623               "contentURL is the string to which it was set.");
   624 };
   626 exports["test ContentScriptOptions Option"] = function(assert, done) {
   627   let loader = Loader(module);
   628   let panel = loader.require("sdk/panel").Panel({
   629       contentScript: "self.postMessage( [typeof self.options.d, self.options] );",
   630       contentScriptWhen: "end",
   631       contentScriptOptions: {a: true, b: [1,2,3], c: "string", d: function(){ return 'test'}},
   632       contentURL: "data:text/html;charset=utf-8,",
   633       onMessage: function(msg) {
   634         assert.equal( msg[0], 'undefined', 'functions are stripped from contentScriptOptions' );
   635         assert.equal( typeof msg[1], 'object', 'object as contentScriptOptions' );
   636         assert.equal( msg[1].a, true, 'boolean in contentScriptOptions' );
   637         assert.equal( msg[1].b.join(), '1,2,3', 'array and numbers in contentScriptOptions' );
   638         assert.equal( msg[1].c, 'string', 'string in contentScriptOptions' );
   639         done();
   640       }
   641     });
   642 };
   644 exports["test console.log in Panel"] = function(assert, done) {
   645   let text = 'console.log() in Panel works!';
   646   let html = '<script>onload = function log(){\
   647                 console.log("' + text + '");\
   648               }</script>';
   650   let { loader } = LoaderWithHookedConsole(module, onMessage);
   651   let { Panel } = loader.require('sdk/panel');
   653   let panel = Panel({
   654     contentURL: 'data:text/html;charset=utf-8,' + encodeURIComponent(html)
   655   });
   657   panel.show();
   659   function onMessage(type, message) {
   660     assert.equal(type, 'log', 'console.log() works');
   661     assert.equal(message, text, 'console.log() works');
   662     panel.destroy();
   663     done();
   664   }
   665 };
   667 if (isWindowPBSupported) {
   668   exports.testPanelDoesNotShowInPrivateWindowNoAnchor = function(assert, done) {
   669     let { loader } = LoaderWithHookedConsole(module, ignorePassingDOMNodeWarning);
   670     let { Panel } = loader.require("sdk/panel");
   671     let browserWindow = getMostRecentBrowserWindow();
   673     assert.equal(isPrivate(browserWindow), false, 'open window is not private');
   675     let panel = Panel({
   676       contentURL: SVG_URL
   677     });
   679     testShowPanel(assert, panel).
   680       then(makeEmptyPrivateBrowserWindow).
   681       then(focus).
   682       then(function(window) {
   683         assert.equal(isPrivate(window), true, 'opened window is private');
   684         assert.pass('private window was focused');
   685         return window;
   686       }).
   687       then(function(window) {
   688         let { promise, resolve } = defer();
   689         let showTries = 0;
   690         let showCount = 0;
   692         panel.on('show', function runTests() {
   693           showCount++;
   695           if (showTries == 2) {
   696             panel.removeListener('show', runTests);
   697             assert.equal(showCount, 1, 'show count is correct - 1');
   698             resolve(window);
   699           }
   700         });
   701         showTries++;
   702         panel.show();
   703         showTries++;
   704         panel.show(null, browserWindow.gBrowser);
   706         return promise;
   707       }).
   708       then(function(window) {
   709         assert.equal(panel.isShowing, true, 'panel is still showing');
   710         panel.hide();
   711         assert.equal(panel.isShowing, false, 'panel is hidden');
   712         return window;
   713       }).
   714       then(close).
   715       then(function() {
   716         assert.pass('private window was closed');
   717       }).
   718       then(testShowPanel.bind(null, assert, panel)).
   719       then(done, assert.fail.bind(assert));
   720   }
   722   exports.testPanelDoesNotShowInPrivateWindowWithAnchor = function(assert, done) {
   723     let { loader } = LoaderWithHookedConsole(module, ignorePassingDOMNodeWarning);
   724     let { Panel } = loader.require("sdk/panel");
   725     let browserWindow = getMostRecentBrowserWindow();
   727     assert.equal(isPrivate(browserWindow), false, 'open window is not private');
   729     let panel = Panel({
   730       contentURL: SVG_URL
   731     });
   733     testShowPanel(assert, panel).
   734       then(makeEmptyPrivateBrowserWindow).
   735       then(focus).
   736       then(function(window) {
   737         assert.equal(isPrivate(window), true, 'opened window is private');
   738         assert.pass('private window was focused');
   739         return window;
   740       }).
   741       then(function(window) {
   742         let { promise, resolve } = defer();
   743         let showTries = 0;
   744         let showCount = 0;
   746         panel.on('show', function runTests() {
   747           showCount++;
   749           if (showTries == 2) {
   750             panel.removeListener('show', runTests);
   751             assert.equal(showCount, 1, 'show count is correct - 1');
   752             resolve(window);
   753           }
   754         });
   755         showTries++;
   756         panel.show(null, window.gBrowser);
   757         showTries++;
   758         panel.show(null, browserWindow.gBrowser);
   760         return promise;
   761       }).
   762       then(function(window) {
   763         assert.equal(panel.isShowing, true, 'panel is still showing');
   764         panel.hide();
   765         assert.equal(panel.isShowing, false, 'panel is hidden');
   766         return window;
   767       }).
   768       then(close).
   769       then(function() {
   770         assert.pass('private window was closed');
   771       }).
   772       then(testShowPanel.bind(null, assert, panel)).
   773       then(done, assert.fail.bind(assert));
   774   }
   775 }
   777 function testShowPanel(assert, panel) {
   778   let { promise, resolve } = defer();
   780   assert.ok(!panel.isShowing, 'the panel is not showing [1]');
   782   panel.once('show', function() {
   783     assert.ok(panel.isShowing, 'the panel is showing');
   785     panel.once('hide', function() {
   786       assert.ok(!panel.isShowing, 'the panel is not showing [2]');
   788       resolve(null);
   789     });
   791     panel.hide();
   792   })
   793   panel.show();
   795   return promise;
   796 }
   798 exports['test Style Applied Only Once'] = function (assert, done) {
   799   let loader = Loader(module);
   800   let panel = loader.require("sdk/panel").Panel({
   801     contentURL: "data:text/html;charset=utf-8,",
   802     contentScript:
   803       'self.port.on("check",function() { self.port.emit("count", document.getElementsByTagName("style").length); });' +
   804       'self.port.on("ping", function (count) { self.port.emit("pong", count); });'
   805   });
   807   panel.port.on('count', function (styleCount) {
   808     assert.equal(styleCount, 1, 'should only have one style');
   809     done();
   810   });
   812   panel.port.on('pong', function (counter) {
   813     panel[--counter % 2 ? 'hide' : 'show']();
   814     panel.port.emit(!counter ? 'check' : 'ping', counter);
   815   });
   817   panel.on('show', init);
   818   panel.show();
   820   function init () {
   821     panel.removeListener('show', init);
   822     panel.port.emit('ping', 10);
   823   }
   824 };
   826 exports['test Only One Panel Open Concurrently'] = function (assert, done) {
   827   const loader = Loader(module);
   828   const { Panel } = loader.require('sdk/panel')
   830   let panelA = Panel({
   831     contentURL: 'about:buildconfig'
   832   });
   834   let panelB = Panel({
   835     contentURL: 'about:buildconfig',
   836     onShow: function () {
   837       // When loading two panels simulataneously, only the second
   838       // should be shown, never showing the first
   839       assert.equal(panelA.isShowing, false, 'First panel is hidden');
   840       assert.equal(panelB.isShowing, true, 'Second panel is showing');
   841       panelC.show();
   842     }
   843   });
   845   let panelC = Panel({
   846     contentURL: 'about:buildconfig',
   847     onShow: function () {
   848       assert.equal(panelA.isShowing, false, 'First panel is hidden');
   849       assert.equal(panelB.isShowing, false, 'Second panel is hidden');
   850       assert.equal(panelC.isShowing, true, 'Third panel is showing');
   851       done();
   852     }
   853   });
   855   panelA.show();
   856   panelB.show();
   857 };
   859 exports['test passing DOM node as first argument'] = function (assert, done) {
   860   let warned = defer();
   861   let shown = defer();
   863   function onMessage(type, message) {
   864     if (type != 'warn') return;
   866     let warning = 'Passing a DOM node to Panel.show() method is an unsupported ' +
   867                   'feature that will be soon replaced. ' +
   868                   'See: https://bugzilla.mozilla.org/show_bug.cgi?id=878877';
   870     assert.equal(type, 'warn',
   871       'the message logged is a warning');
   873     assert.equal(message, warning,
   874       'the warning content is correct');
   876     warned.resolve();
   877   }
   879   let { loader } = LoaderWithHookedConsole(module, onMessage);
   880   let { Panel } = loader.require('sdk/panel');
   881   let { Widget } = loader.require('sdk/widget');
   882   let { document } = getMostRecentBrowserWindow();
   883   let widgetId = 'widget:' + self.id + '-panel-widget';
   885   let panel = Panel({
   886     onShow: function() {
   887       let panelNode = document.getElementById('mainPopupSet').lastChild;
   889       assert.equal(panelNode.anchorNode, widgetNode,
   890         'the panel is properly anchored to the widget');
   892       shown.resolve();
   893     }
   894   });
   896   let widget = Widget({
   897     id: 'panel-widget',
   898     label: 'panel widget',
   899     content: '<i></i>',
   900   });
   902   let widgetNode = document.getElementById(widgetId);
   904   all([warned.promise, shown.promise]).
   905     then(loader.unload).
   906     then(done, assert.fail)
   908   panel.show(widgetNode);
   909 };
   911 // This test is checking that `onpupshowing` events emitted by panel's children
   912 // are not considered.
   913 // See Bug 886329
   914 exports['test nested popups'] = function (assert, done) {
   915   let loader = Loader(module);
   916   let { Panel } = loader.require('sdk/panel');
   917   let { getActiveView } = loader.require('sdk/view/core');
   918   let url = '<select><option>1<option>2<option>3</select>';
   920   let getContentWindow = panel => {
   921     return getActiveView(panel).querySelector('iframe').contentWindow;
   922   }
   924   let panel = Panel({
   925     contentURL: 'data:text/html;charset=utf-8,' + encodeURIComponent(url),
   926     onShow: () => {
   927       ready(getContentWindow(panel)).then(({ window, document }) => {
   928         let select = document.querySelector('select');
   929         let event = document.createEvent('UIEvent');
   931         event.initUIEvent('popupshowing', true, true, window, null);
   932         select.dispatchEvent(event);
   934         assert.equal(
   935           select,
   936           getContentWindow(panel).document.querySelector('select'),
   937           'select is still loaded in panel'
   938         );
   940         done();
   941       });
   942     }
   943   });
   945   panel.show();
   946 };
   948 exports['test emits on url changes'] = function (assert, done) {
   949   let loader = Loader(module);
   950   let { Panel } = loader.require('sdk/panel');
   951   let uriA = 'data:text/html;charset=utf-8,A';
   952   let uriB = 'data:text/html;charset=utf-8,B';
   954   let panel = Panel({
   955     contentURL: uriA,
   956     contentScript: 'new ' + function() {
   957       self.port.on('hi', function() {
   958         self.port.emit('bye', document.URL);
   959       });
   960     }
   961   });
   963   panel.contentURL = uriB;
   964   panel.port.emit('hi', 'hi')
   965   panel.port.on('bye', function(uri) {
   966     assert.equal(uri, uriB, 'message was delivered to new uri');
   967     loader.unload();
   968     done();
   969   });
   970 };
   972 exports['test panel can be constructed without any arguments'] = function (assert) {
   973   const { Panel } = require('sdk/panel');
   975   let panel = Panel();
   976   assert.ok(true, "Creating a panel with no arguments does not throw");
   977 };
   979 exports['test panel CSS'] = function(assert, done) {
   980   const loader = Loader(module);
   981   const { Panel } = loader.require('sdk/panel');
   983   const { getActiveView } = loader.require('sdk/view/core');
   985   const getContentWindow = panel =>
   986     getActiveView(panel).querySelector('iframe').contentWindow;
   988   let panel = Panel({
   989     contentURL: 'data:text/html;charset=utf-8,' + 
   990                 '<div style="background: silver">css test</div>',
   991     contentStyle: 'div { height: 100px; }',
   992     contentStyleFile: CSS_URL,
   993     onShow: () => {
   994       ready(getContentWindow(panel)).then(({ document }) => {
   995         let div = document.querySelector('div');
   997         assert.equal(div.clientHeight, 100, 'Panel contentStyle worked');
   998         assert.equal(div.offsetHeight, 120, 'Panel contentStyleFile worked');
  1000         loader.unload();
  1001         done();
  1002       }).then(null, assert.fail); 
  1004   });
  1006   panel.show();
  1007 };
  1009 exports['test panel CSS list'] = function(assert, done) {
  1010   const loader = Loader(module);
  1011   const { Panel } = loader.require('sdk/panel');
  1013   const { getActiveView } = loader.require('sdk/view/core');
  1015   const getContentWindow = panel =>
  1016     getActiveView(panel).querySelector('iframe').contentWindow;
  1018   let panel = Panel({
  1019     contentURL: 'data:text/html;charset=utf-8,' + 
  1020                 '<div style="width:320px; max-width: 480px!important">css test</div>',
  1021     contentStyleFile: [
  1022       // Highlight evaluation order in this list
  1023       "data:text/css;charset=utf-8,div { border: 1px solid black; }",
  1024       "data:text/css;charset=utf-8,div { border: 10px solid black; }",
  1025       // Highlight evaluation order between contentStylesheet & contentStylesheetFile
  1026       "data:text/css;charset=utf-8s,div { height: 1000px; }",
  1027       // Highlight precedence between the author and user style sheet
  1028       "data:text/css;charset=utf-8,div { width: 200px; max-width: 640px!important}",
  1029     ],
  1030     contentStyle: [
  1031       "div { height: 10px; }",
  1032       "div { height: 100px; }"
  1033     ],
  1034     onShow: () => {
  1035       ready(getContentWindow(panel)).then(({ window, document }) => {
  1036         let div = document.querySelector('div');
  1037         let style = window.getComputedStyle(div);
  1039         assert.equal(div.clientHeight, 100,
  1040           'Panel contentStyle list is evaluated after contentStyleFile');
  1042         assert.equal(div.offsetHeight, 120,
  1043           'Panel contentStyleFile list works');
  1045         assert.equal(style.width, '320px',
  1046           'add-on author/page author stylesheet precedence works');
  1048         assert.equal(style.maxWidth, '480px',
  1049           'add-on author/page author stylesheet !important precedence works');
  1051         loader.unload();
  1052         done();
  1053       }).then(null, assert.fail); 
  1055   });
  1057   panel.show();
  1058 };
  1061 if (isWindowPBSupported) {
  1062   exports.testGetWindow = function(assert, done) {
  1063     let activeWindow = getMostRecentBrowserWindow();
  1064     open(null, { features: {
  1065       toolbar: true,
  1066       chrome: true,
  1067       private: true
  1068     } }).then(function(window) {
  1069       assert.ok(isPrivate(window), 'window is private');
  1070       assert.equal(getWindow(window.gBrowser), null, 'private window elements returns null');
  1071       assert.equal(getWindow(activeWindow.gBrowser), activeWindow, 'non-private window elements returns window');
  1072       close(window).then(done);
  1073     })
  1076 else if (isGlobalPBSupported) {
  1077   exports.testGetWindow = function(assert, done) {
  1078     let activeWindow = getMostRecentBrowserWindow();
  1080     assert.equal(getWindow(activeWindow.gBrowser), activeWindow, 'non-private window elements returns window');
  1081     pb.once('start', function() {
  1082       assert.ok(isPrivate(activeWindow), 'window is private');
  1083       assert.equal(getWindow(activeWindow.gBrowser), activeWindow, 'private window elements returns window');
  1084       open(null, { features: {
  1085         toolbar: true,
  1086         chrome: true
  1087       } }).then(function(window) {
  1088         assert.ok(isPrivate(window), 'window is private');
  1089         assert.equal(getWindow(window.gBrowser), window, 'private window elements returns window');
  1090         assert.equal(getWindow(activeWindow.gBrowser), activeWindow, 'active window elements returns window');
  1092         pb.once('stop', done);
  1093         pb.deactivate();
  1094       })
  1095     });
  1096     pb.activate();
  1100 require("test").run(exports);

mercurial