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.

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

mercurial