addon-sdk/source/test/test-ui-sidebar.js

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/addon-sdk/source/test/test-ui-sidebar.js	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,1478 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.7 +'use strict';
     1.8 +
     1.9 +module.metadata = {
    1.10 +  'engines': {
    1.11 +    'Firefox': '*'
    1.12 +  }
    1.13 +};
    1.14 +
    1.15 +const { Cu } = require('chrome');
    1.16 +const { Loader } = require('sdk/test/loader');
    1.17 +const { show, hide } = require('sdk/ui/sidebar/actions');
    1.18 +const { isShowing } = require('sdk/ui/sidebar/utils');
    1.19 +const { getMostRecentBrowserWindow } = require('sdk/window/utils');
    1.20 +const { open, close, focus, promise: windowPromise } = require('sdk/window/helpers');
    1.21 +const { setTimeout, setImmediate } = require('sdk/timers');
    1.22 +const { isPrivate } = require('sdk/private-browsing');
    1.23 +const data = require('./fixtures');
    1.24 +const { URL } = require('sdk/url');
    1.25 +const { once, off, emit } = require('sdk/event/core');
    1.26 +const { defer, all } = require('sdk/core/promise');
    1.27 +
    1.28 +const { BUILTIN_SIDEBAR_MENUITEMS, isSidebarShowing,
    1.29 +        getSidebarMenuitems, getExtraSidebarMenuitems, makeID, simulateCommand,
    1.30 +        simulateClick, isChecked } = require('./sidebar/utils');
    1.31 +
    1.32 +exports.testSidebarBasicLifeCycle = function(assert, done) {
    1.33 +  const { Sidebar } = require('sdk/ui/sidebar');
    1.34 +  let testName = 'testSidebarBasicLifeCycle';
    1.35 +  let window = getMostRecentBrowserWindow();
    1.36 +  assert.ok(!window.document.getElementById(makeID(testName)), 'sidebar id DNE');
    1.37 +  let sidebarXUL = window.document.getElementById('sidebar');
    1.38 +  assert.ok(sidebarXUL, 'sidebar xul element does exist');
    1.39 +  assert.ok(!getExtraSidebarMenuitems().length, 'there are no extra sidebar menuitems');
    1.40 +
    1.41 +  assert.equal(isSidebarShowing(window), false, 'sidebar is not showing 1');
    1.42 +  let sidebarDetails = {
    1.43 +    id: testName,
    1.44 +    title: 'test',
    1.45 +    url: 'data:text/html;charset=utf-8,'+testName
    1.46 +  };
    1.47 +  let sidebar = Sidebar(sidebarDetails);
    1.48 +
    1.49 +  // test the sidebar attributes
    1.50 +  for (let key of Object.keys(sidebarDetails)) {
    1.51 +    assert.equal(sidebarDetails[key], sidebar[key], 'the attributes match the input');
    1.52 +  }
    1.53 +
    1.54 +  assert.pass('The Sidebar constructor worked');
    1.55 +
    1.56 +  let extraMenuitems = getExtraSidebarMenuitems();
    1.57 +  assert.equal(extraMenuitems.length, 1, 'there is one extra sidebar menuitems');
    1.58 +
    1.59 +  let ele = window.document.getElementById(makeID(testName));
    1.60 +  assert.equal(ele, extraMenuitems[0], 'the only extra menuitem is the one for our sidebar.')
    1.61 +  assert.ok(ele, 'sidebar element was added');
    1.62 +  assert.ok(!isChecked(ele), 'the sidebar is not displayed');
    1.63 +  assert.equal(ele.getAttribute('label'), sidebar.title, 'the sidebar title is the menuitem label')
    1.64 +
    1.65 +  assert.equal(isSidebarShowing(window), false, 'sidebar is not showing 2');
    1.66 +  sidebar.on('show', function() {
    1.67 +    assert.pass('the show event was fired');
    1.68 +    assert.equal(isSidebarShowing(window), true, 'sidebar is not showing 3');
    1.69 +    assert.equal(isShowing(sidebar), true, 'the sidebar is showing');
    1.70 +    assert.ok(isChecked(ele), 'the sidebar is displayed');
    1.71 +
    1.72 +    sidebar.once('hide', function() {
    1.73 +      assert.pass('the hide event was fired');
    1.74 +      assert.ok(!isChecked(ele), 'the sidebar menuitem is not checked');
    1.75 +      assert.equal(isShowing(sidebar), false, 'the sidebar is not showing');
    1.76 +      assert.equal(isSidebarShowing(window), false, 'the sidebar elemnt is hidden');
    1.77 +
    1.78 +      sidebar.once('detach', function() {
    1.79 +        // calling destroy twice should not matter
    1.80 +        sidebar.destroy();
    1.81 +        sidebar.destroy();
    1.82 +
    1.83 +        let sidebarMI = getSidebarMenuitems();
    1.84 +        for (let mi of sidebarMI) {
    1.85 +          assert.ok(BUILTIN_SIDEBAR_MENUITEMS.indexOf(mi.getAttribute('id')) >= 0, 'the menuitem is for a built-in sidebar')
    1.86 +          assert.ok(!isChecked(mi), 'no sidebar menuitem is checked');
    1.87 +        }
    1.88 +
    1.89 +        assert.ok(!window.document.getElementById(makeID(testName)), 'sidebar id DNE');
    1.90 +        assert.pass('calling destroy worked without error');
    1.91 +
    1.92 +        done();
    1.93 +      });
    1.94 +    });
    1.95 +
    1.96 +    sidebar.hide();
    1.97 +    assert.pass('hiding sidebar..');
    1.98 +  });
    1.99 +
   1.100 +  sidebar.show();
   1.101 +  assert.pass('showing sidebar..');
   1.102 +}
   1.103 +
   1.104 +exports.testSideBarIsInNewWindows = function(assert, done) {
   1.105 +  const { Sidebar } = require('sdk/ui/sidebar');
   1.106 +  let testName = 'testSideBarIsInNewWindows';
   1.107 +  let sidebar = Sidebar({
   1.108 +    id: testName,
   1.109 +    title: testName,
   1.110 +    url: 'data:text/html;charset=utf-8,'+testName
   1.111 +  });
   1.112 +
   1.113 +  let startWindow = getMostRecentBrowserWindow();
   1.114 +  let ele = startWindow.document.getElementById(makeID(testName));
   1.115 +  assert.ok(ele, 'sidebar element was added');
   1.116 +
   1.117 +  open().then(function(window) {
   1.118 +      let ele = window.document.getElementById(makeID(testName));
   1.119 +      assert.ok(ele, 'sidebar element was added');
   1.120 +
   1.121 +      // calling destroy twice should not matter
   1.122 +      sidebar.destroy();
   1.123 +      sidebar.destroy();
   1.124 +
   1.125 +      assert.ok(!window.document.getElementById(makeID(testName)), 'sidebar id DNE');
   1.126 +      assert.ok(!startWindow.document.getElementById(makeID(testName)), 'sidebar id DNE');
   1.127 +
   1.128 +      close(window).then(done, assert.fail);
   1.129 +  })
   1.130 +}
   1.131 +
   1.132 +exports.testSideBarIsShowingInNewWindows = function(assert, done) {
   1.133 +  const { Sidebar } = require('sdk/ui/sidebar');
   1.134 +  let testName = 'testSideBarIsShowingInNewWindows';
   1.135 +  let sidebar = Sidebar({
   1.136 +    id: testName,
   1.137 +    title: testName,
   1.138 +    url: URL('data:text/html;charset=utf-8,'+testName)
   1.139 +  });
   1.140 +
   1.141 +  let startWindow = getMostRecentBrowserWindow();
   1.142 +  let ele = startWindow.document.getElementById(makeID(testName));
   1.143 +  assert.ok(ele, 'sidebar element was added');
   1.144 +
   1.145 +  let oldEle = ele;
   1.146 +  sidebar.once('attach', function() {
   1.147 +    assert.pass('attach event fired');
   1.148 +
   1.149 +    sidebar.once('show', function() {
   1.150 +      assert.pass('show event fired');
   1.151 +
   1.152 +      sidebar.once('show', function() {
   1.153 +        let window = getMostRecentBrowserWindow();
   1.154 +        assert.notEqual(startWindow, window, 'window is new');
   1.155 +
   1.156 +        let sb = window.document.getElementById('sidebar');
   1.157 +        if (sb && sb.docShell && sb.contentDocument && sb.contentDocument.getElementById('web-panels-browser')) {
   1.158 +          end();
   1.159 +        }
   1.160 +        else {
   1.161 +          sb.addEventListener('DOMWindowCreated', end, false);
   1.162 +        }
   1.163 +
   1.164 +        function end() {
   1.165 +          sb.removeEventListener('DOMWindowCreated', end, false);
   1.166 +          let webPanelBrowser = sb.contentDocument.getElementById('web-panels-browser');
   1.167 +
   1.168 +          let ele = window.document.getElementById(makeID(testName));
   1.169 +
   1.170 +          assert.ok(ele, 'sidebar element was added 2');
   1.171 +          assert.ok(isChecked(ele), 'the sidebar is checked');
   1.172 +          assert.notEqual(ele, oldEle, 'there are two different sidebars');
   1.173 +
   1.174 +          assert.equal(isShowing(sidebar), true, 'the sidebar is showing in new window');
   1.175 +
   1.176 +
   1.177 +            sidebar.destroy();
   1.178 +
   1.179 +            assert.equal(isShowing(sidebar), false, 'the sidebar is not showing');
   1.180 +            assert.ok(!isSidebarShowing(window), 'sidebar in most recent window is not showing');
   1.181 +            assert.ok(!isSidebarShowing(startWindow), 'sidebar in most start window is not showing');
   1.182 +            assert.ok(!window.document.getElementById(makeID(testName)), 'sidebar id DNE');
   1.183 +            assert.ok(!startWindow.document.getElementById(makeID(testName)), 'sidebar id DNE');
   1.184 +
   1.185 +            setTimeout(function() {
   1.186 +              close(window).then(done, assert.fail);
   1.187 +            });
   1.188 +        }
   1.189 +      });
   1.190 +
   1.191 +      startWindow.OpenBrowserWindow();
   1.192 +    });
   1.193 +  });
   1.194 +
   1.195 +  show(sidebar);
   1.196 +  assert.pass('showing the sidebar');
   1.197 +}
   1.198 +
   1.199 +// TODO: determine if this is acceptable..
   1.200 +/*
   1.201 +exports.testAddonGlobalSimple = function(assert, done) {
   1.202 +  const { Sidebar } = require('sdk/ui/sidebar');
   1.203 +  let testName = 'testAddonGlobalSimple';
   1.204 +  let sidebar = Sidebar({
   1.205 +    id: testName,
   1.206 +    title: testName,
   1.207 +    url: data.url('test-sidebar-addon-global.html')
   1.208 +  });
   1.209 +
   1.210 +  sidebar.on('show', function({worker}) {
   1.211 +    assert.pass('sidebar was attached');
   1.212 +    assert.ok(!!worker, 'attach event has worker');
   1.213 +
   1.214 +    worker.port.on('X', function(msg) {
   1.215 +      assert.equal(msg, '23', 'the final message is correct');
   1.216 +
   1.217 +      sidebar.destroy();
   1.218 +
   1.219 +      done();
   1.220 +    });
   1.221 +    worker.port.emit('X', '2');
   1.222 +  });
   1.223 +  show(sidebar);
   1.224 +}
   1.225 +*/
   1.226 +
   1.227 +exports.testAddonGlobalComplex = function(assert, done) {
   1.228 +  const { Sidebar } = require('sdk/ui/sidebar');
   1.229 +  let testName = 'testAddonGlobalComplex';
   1.230 +  let sidebar = Sidebar({
   1.231 +    id: testName,
   1.232 +    title: testName,
   1.233 +    url: data.url('test-sidebar-addon-global.html')
   1.234 +  });
   1.235 +
   1.236 +  sidebar.on('attach', function(worker) {
   1.237 +    assert.pass('sidebar was attached');
   1.238 +    assert.ok(!!worker, 'attach event has worker');
   1.239 +
   1.240 +    worker.port.once('Y', function(msg) {
   1.241 +      assert.equal(msg, '1', 'got event from worker');
   1.242 +
   1.243 +      worker.port.on('X', function(msg) {
   1.244 +        assert.equal(msg, '123', 'the final message is correct');
   1.245 +
   1.246 +        sidebar.destroy();
   1.247 +
   1.248 +        done();
   1.249 +      });
   1.250 +      worker.port.emit('X', msg + '2');
   1.251 +    })
   1.252 +  });
   1.253 +
   1.254 +  show(sidebar);
   1.255 +}
   1.256 +
   1.257 +exports.testAddonReady = function(assert, done) {
   1.258 +  const { Sidebar } = require('sdk/ui/sidebar');
   1.259 +  let testName = 'testAddonReady';
   1.260 +  let sidebar = Sidebar({
   1.261 +    id: testName,
   1.262 +    title: testName,
   1.263 +    url: data.url('test-sidebar-addon-global.html'),
   1.264 +    onReady: function(worker) {
   1.265 +      assert.pass('sidebar was attached');
   1.266 +      assert.ok(!!worker, 'attach event has worker');
   1.267 +
   1.268 +      worker.port.on('X', function(msg) {
   1.269 +        assert.equal(msg, '123', 'the final message is correct');
   1.270 +
   1.271 +        sidebar.destroy();
   1.272 +
   1.273 +        done();
   1.274 +      });
   1.275 +
   1.276 +      worker.port.emit('X', '12');
   1.277 +    }
   1.278 +  });
   1.279 +
   1.280 +  show(sidebar);
   1.281 +}
   1.282 +
   1.283 +exports.testShowingOneSidebarAfterAnother = function(assert, done) {
   1.284 +  const { Sidebar } = require('sdk/ui/sidebar');
   1.285 +  let testName = 'testShowingOneSidebarAfterAnother';
   1.286 +
   1.287 +  let sidebar1 = Sidebar({
   1.288 +    id: testName + '1',
   1.289 +    title: testName + '1',
   1.290 +    url:  'data:text/html;charset=utf-8,'+ testName + 1
   1.291 +  });
   1.292 +  let sidebar2 = Sidebar({
   1.293 +    id: testName + '2',
   1.294 +    title: testName + '2',
   1.295 +    url:  'data:text/html;charset=utf-8,'+ testName + 2
   1.296 +  });
   1.297 +
   1.298 +  let window = getMostRecentBrowserWindow();
   1.299 +  let IDs = [ sidebar1.id, sidebar2.id ];
   1.300 +
   1.301 +  let extraMenuitems = getExtraSidebarMenuitems(window);
   1.302 +  assert.equal(extraMenuitems.length, 2, 'there are two extra sidebar menuitems');
   1.303 +
   1.304 +  function testShowing(sb1, sb2, sbEle) {
   1.305 +    assert.equal(isShowing(sidebar1), sb1);
   1.306 +    assert.equal(isShowing(sidebar2), sb2);
   1.307 +    assert.equal(isSidebarShowing(window), sbEle);
   1.308 +  }
   1.309 +  testShowing(false, false, false);
   1.310 +
   1.311 +  sidebar1.once('show', function() {
   1.312 +    testShowing(true, false, true);
   1.313 +    for (let mi of getExtraSidebarMenuitems(window)) {
   1.314 +      let menuitemID = mi.getAttribute('id').replace(/^jetpack-sidebar-/, '');
   1.315 +      assert.ok(IDs.indexOf(menuitemID) >= 0, 'the extra menuitem is for one of our test sidebars');
   1.316 +      assert.equal(isChecked(mi), menuitemID == sidebar1.id, 'the test sidebar menuitem has the correct checked value');
   1.317 +    }
   1.318 +
   1.319 +    sidebar2.once('show', function() {
   1.320 +      testShowing(false, true, true);
   1.321 +      for (let mi of getExtraSidebarMenuitems(window)) {
   1.322 +        let menuitemID = mi.getAttribute('id').replace(/^jetpack-sidebar-/, '');
   1.323 +        assert.ok(IDs.indexOf(menuitemID) >= 0, 'the extra menuitem is for one of our test sidebars');
   1.324 +        assert.equal(isChecked(mi), menuitemID == sidebar2.id, 'the test sidebar menuitem has the correct checked value');
   1.325 +      }
   1.326 +
   1.327 +      sidebar1.destroy();
   1.328 +      sidebar2.destroy();
   1.329 +
   1.330 +      testShowing(false, false, false);
   1.331 +
   1.332 +      done();
   1.333 +    });
   1.334 +
   1.335 +    show(sidebar2);
   1.336 +    assert.pass('showing sidebar 2');
   1.337 +  })
   1.338 +  show(sidebar1);
   1.339 +  assert.pass('showing sidebar 1');
   1.340 +}
   1.341 +
   1.342 +exports.testSidebarUnload = function(assert, done) {
   1.343 +  const { Sidebar } = require('sdk/ui/sidebar');
   1.344 +  let testName = 'testSidebarUnload';
   1.345 +  let loader = Loader(module);
   1.346 +
   1.347 +  let window = getMostRecentBrowserWindow();
   1.348 +
   1.349 +  assert.equal(isPrivate(window), false, 'the current window is not private');
   1.350 +
   1.351 +  let sidebar = loader.require('sdk/ui/sidebar').Sidebar({
   1.352 +    id: testName,
   1.353 +    title: testName,
   1.354 +    url:  'data:text/html;charset=utf-8,'+ testName,
   1.355 +    onShow: function() {
   1.356 +      assert.pass('onShow works for Sidebar');
   1.357 +      loader.unload();
   1.358 +
   1.359 +      let sidebarMI = getSidebarMenuitems();
   1.360 +      for (let mi of sidebarMI) {
   1.361 +        assert.ok(BUILTIN_SIDEBAR_MENUITEMS.indexOf(mi.getAttribute('id')) >= 0, 'the menuitem is for a built-in sidebar')
   1.362 +        assert.ok(!isChecked(mi), 'no sidebar menuitem is checked');
   1.363 +      }
   1.364 +      assert.ok(!window.document.getElementById(makeID(testName)), 'sidebar id DNE');
   1.365 +      assert.equal(isSidebarShowing(window), false, 'the sidebar is not showing');
   1.366 +
   1.367 +      done();
   1.368 +    }
   1.369 +  })
   1.370 +
   1.371 +  sidebar.show();
   1.372 +  assert.pass('showing the sidebar');
   1.373 +}
   1.374 +
   1.375 +exports.testRemoteContent = function(assert) {
   1.376 +  const { Sidebar } = require('sdk/ui/sidebar');
   1.377 +  let testName = 'testRemoteContent';
   1.378 +  try {
   1.379 +    let sidebar = Sidebar({
   1.380 +      id: testName,
   1.381 +      title: testName,
   1.382 +      url: 'http://dne.xyz.mozilla.org'
   1.383 +    });
   1.384 +    assert.fail('a bad sidebar was created..');
   1.385 +    sidebar.destroy();
   1.386 +  }
   1.387 +  catch(e) {
   1.388 +    assert.ok(/The option "url" must be a valid local URI\./.test(e), 'remote content is not acceptable');
   1.389 +  }
   1.390 +}
   1.391 +
   1.392 +exports.testInvalidURL = function(assert) {
   1.393 +  const { Sidebar } = require('sdk/ui/sidebar');
   1.394 +  let testName = 'testInvalidURL';
   1.395 +  try {
   1.396 +    let sidebar = Sidebar({
   1.397 +      id: testName,
   1.398 +      title: testName,
   1.399 +      url: 'http:mozilla.org'
   1.400 +    });
   1.401 +    assert.fail('a bad sidebar was created..');
   1.402 +    sidebar.destroy();
   1.403 +  }
   1.404 +  catch(e) {
   1.405 +    assert.ok(/The option "url" must be a valid local URI\./.test(e), 'invalid URIs are not acceptable');
   1.406 +  }
   1.407 +}
   1.408 +
   1.409 +exports.testInvalidURLType = function(assert) {
   1.410 +  const { Sidebar } = require('sdk/ui/sidebar');
   1.411 +  let testName = 'testInvalidURLType';
   1.412 +  try {
   1.413 +    let sidebar = Sidebar({
   1.414 +      id: testName,
   1.415 +      title: testName
   1.416 +    });
   1.417 +    assert.fail('a bad sidebar was created..');
   1.418 +    sidebar.destroy();
   1.419 +  }
   1.420 +  catch(e) {
   1.421 +    assert.ok(/The option "url" must be a valid local URI\./.test(e), 'invalid URIs are not acceptable');
   1.422 +  }
   1.423 +}
   1.424 +
   1.425 +exports.testInvalidTitle = function(assert) {
   1.426 +  const { Sidebar } = require('sdk/ui/sidebar');
   1.427 +  let testName = 'testInvalidTitle';
   1.428 +  try {
   1.429 +    let sidebar = Sidebar({
   1.430 +      id: testName,
   1.431 +      title: '',
   1.432 +      url: 'data:text/html;charset=utf-8,'+testName
   1.433 +    });
   1.434 +    assert.fail('a bad sidebar was created..');
   1.435 +    sidebar.destroy();
   1.436 +  }
   1.437 +  catch(e) {
   1.438 +    assert.equal('The option "title" must be one of the following types: string', e.message, 'invalid titles are not acceptable');
   1.439 +  }
   1.440 +}
   1.441 +
   1.442 +exports.testInvalidID = function(assert) {
   1.443 +  const { Sidebar } = require('sdk/ui/sidebar');
   1.444 +  let testName = 'testInvalidID';
   1.445 +  try {
   1.446 +    let sidebar = Sidebar({
   1.447 +      id: '!',
   1.448 +      title: testName,
   1.449 +      url: 'data:text/html;charset=utf-8,'+testName
   1.450 +    });
   1.451 +    assert.fail('a bad sidebar was created..');
   1.452 +    sidebar.destroy();
   1.453 +  }
   1.454 +  catch(e) {
   1.455 +    assert.ok(/The option "id" must be a valid alphanumeric id/.test(e), 'invalid ids are not acceptable');
   1.456 +  }
   1.457 +}
   1.458 +
   1.459 +exports.testInvalidBlankID = function(assert) {
   1.460 +  const { Sidebar } = require('sdk/ui/sidebar');
   1.461 +  let testName = 'testInvalidBlankID';
   1.462 +  try {
   1.463 +    let sidebar = Sidebar({
   1.464 +      id: '',
   1.465 +      title: testName,
   1.466 +      url: 'data:text/html;charset=utf-8,'+testName
   1.467 +    });
   1.468 +    assert.fail('a bad sidebar was created..');
   1.469 +    sidebar.destroy();
   1.470 +  }
   1.471 +  catch(e) {
   1.472 +    assert.ok(/The option "id" must be a valid alphanumeric id/.test(e), 'invalid ids are not acceptable');
   1.473 +  }
   1.474 +}
   1.475 +
   1.476 +exports.testInvalidNullID = function(assert) {
   1.477 +  const { Sidebar } = require('sdk/ui/sidebar');
   1.478 +  let testName = 'testInvalidNullID';
   1.479 +  try {
   1.480 +    let sidebar = Sidebar({
   1.481 +      id: null,
   1.482 +      title: testName,
   1.483 +      url: 'data:text/html;charset=utf-8,'+testName
   1.484 +    });
   1.485 +    assert.fail('a bad sidebar was created..');
   1.486 +    sidebar.destroy();
   1.487 +  }
   1.488 +  catch(e) {
   1.489 +    assert.ok(/The option "id" must be a valid alphanumeric id/.test(e), 'invalid ids are not acceptable');
   1.490 +  }
   1.491 +}
   1.492 +
   1.493 +exports.testUndefinedID = function(assert) {
   1.494 +  const { Sidebar } = require('sdk/ui/sidebar');
   1.495 +  let testName = 'testInvalidUndefinedID';
   1.496 +
   1.497 +  try {
   1.498 +    let sidebar = Sidebar({
   1.499 +      title: testName,
   1.500 +      url: 'data:text/html;charset=utf-8,' + testName
   1.501 +    });
   1.502 +
   1.503 +    assert.ok(sidebar.id, 'an undefined id was accepted, id was creawted: ' + sidebar.id);
   1.504 +    assert.ok(getMostRecentBrowserWindow().document.getElementById(makeID(sidebar.id)), 'the sidebar element was found');
   1.505 +
   1.506 +    sidebar.destroy();
   1.507 +  }
   1.508 +  catch(e) {
   1.509 +    assert.fail('undefined ids are acceptable');
   1.510 +    assert.fail(e.message);
   1.511 +  }
   1.512 +}
   1.513 +
   1.514 +// TEST: edge case where web panel is destroyed while loading
   1.515 +exports.testDestroyEdgeCaseBug = function(assert, done) {
   1.516 +  const { Sidebar } = require('sdk/ui/sidebar');
   1.517 +  let testName = 'testDestroyEdgeCaseBug';
   1.518 +  let window = getMostRecentBrowserWindow();
   1.519 +  let sidebar = Sidebar({
   1.520 +    id: testName,
   1.521 +    title: testName,
   1.522 +    url: 'data:text/html;charset=utf-8,'+testName
   1.523 +  });
   1.524 +
   1.525 +  // NOTE: purposely not listening to show event b/c the event happens
   1.526 +  //       between now and then.
   1.527 +  sidebar.show();
   1.528 +
   1.529 +  assert.equal(isPrivate(window), false, 'the new window is not private');
   1.530 +  assert.equal(isSidebarShowing(window), true, 'the sidebar is showing');
   1.531 +
   1.532 +  //assert.equal(isShowing(sidebar), true, 'the sidebar is showing');
   1.533 +
   1.534 +  open().then(focus).then(function(window2) {
   1.535 +    assert.equal(isPrivate(window2), false, 'the new window is not private');
   1.536 +    assert.equal(isSidebarShowing(window2), false, 'the sidebar is not showing');
   1.537 +    assert.equal(isShowing(sidebar), false, 'the sidebar is not showing');
   1.538 +
   1.539 +    sidebar.destroy();
   1.540 +    assert.pass('destroying the sidebar');
   1.541 +
   1.542 +    close(window2).then(function() {
   1.543 +      let loader = Loader(module);
   1.544 +
   1.545 +      assert.equal(isPrivate(window), false, 'the current window is not private');
   1.546 +
   1.547 +      let sidebar = loader.require('sdk/ui/sidebar').Sidebar({
   1.548 +        id: testName,
   1.549 +        title: testName,
   1.550 +        url:  'data:text/html;charset=utf-8,'+ testName,
   1.551 +        onShow: function() {
   1.552 +          assert.pass('onShow works for Sidebar');
   1.553 +          loader.unload();
   1.554 +
   1.555 +          let sidebarMI = getSidebarMenuitems();
   1.556 +          for (let mi of sidebarMI) {
   1.557 +            assert.ok(BUILTIN_SIDEBAR_MENUITEMS.indexOf(mi.getAttribute('id')) >= 0, 'the menuitem is for a built-in sidebar')
   1.558 +            assert.ok(!isChecked(mi), 'no sidebar menuitem is checked');
   1.559 +          }
   1.560 +          assert.ok(!window.document.getElementById(makeID(testName)), 'sidebar id DNE');
   1.561 +          assert.equal(isSidebarShowing(window), false, 'the sidebar is not showing');
   1.562 +
   1.563 +          done();
   1.564 +        }
   1.565 +      })
   1.566 +
   1.567 +      sidebar.show();
   1.568 +      assert.pass('showing the sidebar');
   1.569 +
   1.570 +    });
   1.571 +  });
   1.572 +}
   1.573 +
   1.574 +exports.testClickingACheckedMenuitem = function(assert, done) {
   1.575 +  const { Sidebar } = require('sdk/ui/sidebar');
   1.576 +  let testName = 'testClickingACheckedMenuitem';
   1.577 +  let window = getMostRecentBrowserWindow();
   1.578 +  let sidebar = Sidebar({
   1.579 +    id: testName,
   1.580 +    title: testName,
   1.581 +    url: 'data:text/html;charset=utf-8,'+testName,
   1.582 +  });
   1.583 +
   1.584 +  sidebar.show().then(function() {
   1.585 +    assert.pass('the show callback works');
   1.586 +
   1.587 +    sidebar.once('hide', function() {
   1.588 +      assert.pass('clicking the menuitem after the sidebar has shown hides it.');
   1.589 +      sidebar.destroy();
   1.590 +      done();
   1.591 +    });
   1.592 +
   1.593 +    let menuitem = window.document.getElementById(makeID(sidebar.id));
   1.594 +    simulateCommand(menuitem);
   1.595 +  });
   1.596 +};
   1.597 +
   1.598 +exports.testTitleSetter = function(assert, done) {
   1.599 +  const { Sidebar } = require('sdk/ui/sidebar');
   1.600 +  let testName = 'testTitleSetter';
   1.601 +  let { document } = getMostRecentBrowserWindow();
   1.602 +
   1.603 +  let sidebar1 = Sidebar({
   1.604 +    id: testName,
   1.605 +    title: testName,
   1.606 +    url: 'data:text/html;charset=utf-8,'+testName,
   1.607 +  });
   1.608 +
   1.609 +  assert.equal(sidebar1.title, testName, 'title getter works');
   1.610 +
   1.611 +  sidebar1.show().then(function() {
   1.612 +    assert.equal(document.getElementById(makeID(sidebar1.id)).getAttribute('label'),
   1.613 +                 testName,
   1.614 +                 'the menuitem label is correct');
   1.615 +
   1.616 +    assert.equal(document.getElementById('sidebar-title').value, testName, 'the menuitem label is correct');
   1.617 +
   1.618 +    sidebar1.title = 'foo';
   1.619 +
   1.620 +    assert.equal(sidebar1.title, 'foo', 'title getter works');
   1.621 +
   1.622 +    assert.equal(document.getElementById(makeID(sidebar1.id)).getAttribute('label'),
   1.623 +                 'foo',
   1.624 +                 'the menuitem label was updated');
   1.625 +
   1.626 +    assert.equal(document.getElementById('sidebar-title').value, 'foo', 'the sidebar title was updated');
   1.627 +
   1.628 +    sidebar1.destroy();
   1.629 +    done();
   1.630 +  }, assert.fail);
   1.631 +}
   1.632 +
   1.633 +exports.testURLSetter = function(assert, done) {
   1.634 +  const { Sidebar } = require('sdk/ui/sidebar');
   1.635 +  let testName = 'testURLSetter';
   1.636 +  let window = getMostRecentBrowserWindow();
   1.637 +  let { document } = window;
   1.638 +  let url = 'data:text/html;charset=utf-8,'+testName;
   1.639 +
   1.640 +  let sidebar1 = Sidebar({
   1.641 +    id: testName,
   1.642 +    title: testName,
   1.643 +    url: url
   1.644 +  });
   1.645 +
   1.646 +  assert.equal(sidebar1.url, url, 'url getter works');
   1.647 +  assert.equal(isShowing(sidebar1), false, 'the sidebar is not showing');
   1.648 +  assert.ok(!isChecked(document.getElementById(makeID(sidebar1.id))),
   1.649 +               'the menuitem is not checked');
   1.650 +  assert.equal(isSidebarShowing(window), false, 'the new window sidebar is not showing');
   1.651 +
   1.652 +  windowPromise(window.OpenBrowserWindow(), 'load').then(function(window) {
   1.653 +    let { document } = window;
   1.654 +    assert.pass('new window was opened');
   1.655 +
   1.656 +    sidebar1.show().then(function() {
   1.657 +      assert.equal(isShowing(sidebar1), true, 'the sidebar is showing');
   1.658 +      assert.ok(isChecked(document.getElementById(makeID(sidebar1.id))),
   1.659 +                   'the menuitem is checked');
   1.660 +      assert.ok(isSidebarShowing(window), 'the new window sidebar is showing');
   1.661 +
   1.662 +      sidebar1.once('show', function() {
   1.663 +        assert.pass('setting the sidebar.url causes a show event');
   1.664 +
   1.665 +        assert.equal(isShowing(sidebar1), true, 'the sidebar is showing');
   1.666 +        assert.ok(isSidebarShowing(window), 'the new window sidebar is still showing');
   1.667 +
   1.668 +        assert.ok(isChecked(document.getElementById(makeID(sidebar1.id))),
   1.669 +                     'the menuitem is still checked');
   1.670 +
   1.671 +        sidebar1.destroy();
   1.672 +
   1.673 +        close(window).then(done);
   1.674 +      });
   1.675 +
   1.676 +      sidebar1.url = (url + '1');
   1.677 +
   1.678 +      assert.equal(sidebar1.url, (url + '1'), 'url getter works');
   1.679 +      assert.equal(isShowing(sidebar1), true, 'the sidebar is showing');
   1.680 +      assert.ok(isSidebarShowing(window), 'the new window sidebar is showing');
   1.681 +    }, assert.fail);
   1.682 +  }, assert.fail);
   1.683 +}
   1.684 +
   1.685 +exports.testDuplicateID = function(assert) {
   1.686 +  const { Sidebar } = require('sdk/ui/sidebar');
   1.687 +  let testName = 'testDuplicateID';
   1.688 +  let window = getMostRecentBrowserWindow();
   1.689 +  let { document } = window;
   1.690 +  let url = 'data:text/html;charset=utf-8,'+testName;
   1.691 +
   1.692 +  let sidebar1 = Sidebar({
   1.693 +    id: testName,
   1.694 +    title: testName,
   1.695 +    url: url
   1.696 +  });
   1.697 +
   1.698 +  assert.throws(function() {
   1.699 +    Sidebar({
   1.700 +      id: testName,
   1.701 +      title: testName + 1,
   1.702 +      url: url + 2
   1.703 +    }).destroy();
   1.704 +  }, /The ID .+ seems already used\./i, 'duplicate IDs will throw errors');
   1.705 +
   1.706 +  sidebar1.destroy();
   1.707 +}
   1.708 +
   1.709 +exports.testURLSetterToSameValueReloadsSidebar = function(assert, done) {
   1.710 +  const { Sidebar } = require('sdk/ui/sidebar');
   1.711 +  let testName = 'testURLSetterToSameValueReloadsSidebar';
   1.712 +  let window = getMostRecentBrowserWindow();
   1.713 +  let { document } = window;
   1.714 +  let url = 'data:text/html;charset=utf-8,'+testName;
   1.715 +
   1.716 +  let sidebar1 = Sidebar({
   1.717 +    id: testName,
   1.718 +    title: testName,
   1.719 +    url: url
   1.720 +  });
   1.721 +
   1.722 +  assert.equal(sidebar1.url, url, 'url getter works');
   1.723 +  assert.equal(isShowing(sidebar1), false, 'the sidebar is not showing');
   1.724 +  assert.ok(!isChecked(document.getElementById(makeID(sidebar1.id))),
   1.725 +               'the menuitem is not checked');
   1.726 +  assert.equal(isSidebarShowing(window), false, 'the new window sidebar is not showing');
   1.727 +
   1.728 +  windowPromise(window.OpenBrowserWindow(), 'load').then(function(window) {
   1.729 +    let { document } = window;
   1.730 +    assert.pass('new window was opened');
   1.731 +
   1.732 +    sidebar1.show().then(function() {
   1.733 +      assert.equal(isShowing(sidebar1), true, 'the sidebar is showing');
   1.734 +      assert.ok(isChecked(document.getElementById(makeID(sidebar1.id))),
   1.735 +                   'the menuitem is checked');
   1.736 +      assert.ok(isSidebarShowing(window), 'the new window sidebar is showing');
   1.737 +
   1.738 +      sidebar1.once('show', function() {
   1.739 +        assert.pass('setting the sidebar.url causes a show event');
   1.740 +
   1.741 +        assert.equal(isShowing(sidebar1), true, 'the sidebar is showing');
   1.742 +        assert.ok(isSidebarShowing(window), 'the new window sidebar is still showing');
   1.743 +
   1.744 +        assert.ok(isChecked(document.getElementById(makeID(sidebar1.id))),
   1.745 +                     'the menuitem is still checked');
   1.746 +
   1.747 +        sidebar1.destroy();
   1.748 +
   1.749 +        close(window).then(done);
   1.750 +      });
   1.751 +
   1.752 +      sidebar1.url = url;
   1.753 +
   1.754 +      assert.equal(sidebar1.url, url, 'url getter works');
   1.755 +      assert.equal(isShowing(sidebar1), true, 'the sidebar is showing');
   1.756 +      assert.ok(isSidebarShowing(window), 'the new window sidebar is showing');
   1.757 +    }, assert.fail);
   1.758 +  }, assert.fail);
   1.759 +}
   1.760 +
   1.761 +exports.testShowingInOneWindowDoesNotAffectOtherWindows = function(assert, done) {
   1.762 +  const { Sidebar } = require('sdk/ui/sidebar');
   1.763 +  let testName = 'testShowingInOneWindowDoesNotAffectOtherWindows';
   1.764 +  let window1 = getMostRecentBrowserWindow();
   1.765 +  let url = 'data:text/html;charset=utf-8,'+testName;
   1.766 +
   1.767 +  let sidebar1 = Sidebar({
   1.768 +    id: testName,
   1.769 +    title: testName,
   1.770 +    url: url
   1.771 +  });
   1.772 +
   1.773 +  assert.equal(sidebar1.url, url, 'url getter works');
   1.774 +  assert.equal(isShowing(sidebar1), false, 'the sidebar is not showing');
   1.775 +  let checkCount = 1;
   1.776 +  function checkSidebarShowing(window, expected) {
   1.777 +    assert.pass('check count ' + checkCount++);
   1.778 +
   1.779 +    let mi = window.document.getElementById(makeID(sidebar1.id));
   1.780 +    if (mi) {
   1.781 +      assert.equal(isChecked(mi), expected,
   1.782 +                   'the menuitem is not checked');
   1.783 +    }
   1.784 +    assert.equal(isSidebarShowing(window), expected || false, 'the new window sidebar is not showing');
   1.785 +  }
   1.786 +  checkSidebarShowing(window1, false);
   1.787 +
   1.788 +  windowPromise(window1.OpenBrowserWindow(), 'load').then(function(window) {
   1.789 +    let { document } = window;
   1.790 +    assert.pass('new window was opened!');
   1.791 +
   1.792 +    // waiting for show
   1.793 +    sidebar1.once('show', function() {
   1.794 +      // check state of the new window
   1.795 +      assert.equal(isShowing(sidebar1), true, 'the sidebar is showing');
   1.796 +      checkSidebarShowing(window, true);
   1.797 +
   1.798 +      // check state of old window
   1.799 +      checkSidebarShowing(window1, false);
   1.800 +
   1.801 +      // waiting for show using url setter
   1.802 +      sidebar1.once('show', function() {
   1.803 +        assert.pass('setting the sidebar.url causes a new show event');
   1.804 +
   1.805 +        // check state of the new window
   1.806 +        assert.equal(isShowing(sidebar1), true, 'the sidebar is showing');
   1.807 +        checkSidebarShowing(window, true);
   1.808 +
   1.809 +        // check state of old window
   1.810 +        checkSidebarShowing(window1, false);
   1.811 +
   1.812 +        // calling destroy() twice should not matter
   1.813 +        sidebar1.destroy();
   1.814 +        sidebar1.destroy();
   1.815 +
   1.816 +        // check state of the new window
   1.817 +        assert.equal(isShowing(sidebar1), false, 'the sidebar is not showing');
   1.818 +        checkSidebarShowing(window, undefined);
   1.819 +
   1.820 +        // check state of old window
   1.821 +        checkSidebarShowing(window1, undefined);
   1.822 +
   1.823 +        close(window).then(done);
   1.824 +      });
   1.825 +
   1.826 +      assert.pass('setting sidebar1.url');
   1.827 +      sidebar1.url += '1';
   1.828 +      assert.pass('set sidebar1.url');
   1.829 +    });
   1.830 +
   1.831 +    sidebar1.show();
   1.832 +  }, assert.fail);
   1.833 +}
   1.834 +
   1.835 +exports.testHidingAHiddenSidebarRejects = function(assert, done) {
   1.836 +  const { Sidebar } = require('sdk/ui/sidebar');
   1.837 +  let testName = 'testHidingAHiddenSidebarRejects';
   1.838 +  let url = 'data:text/html;charset=utf-8,'+testName;
   1.839 +  let sidebar = Sidebar({
   1.840 +    id: testName,
   1.841 +    title: testName,
   1.842 +    url: url
   1.843 +  });
   1.844 +
   1.845 +  sidebar.hide().then(assert.fail, assert.pass).then(function() {
   1.846 +    sidebar.destroy();
   1.847 +    done();
   1.848 +  }, assert.fail);
   1.849 +}
   1.850 +
   1.851 +exports.testGCdSidebarsOnUnload = function(assert, done) {
   1.852 +  const loader = Loader(module);
   1.853 +  const { Sidebar } = loader.require('sdk/ui/sidebar');
   1.854 +  const window = getMostRecentBrowserWindow();
   1.855 +
   1.856 +  let testName = 'testGCdSidebarsOnUnload';
   1.857 +  let url = 'data:text/html;charset=utf-8,'+testName;
   1.858 +
   1.859 +  assert.equal(isSidebarShowing(window), false, 'the sidebar is not showing');
   1.860 +
   1.861 +  // IMPORTANT: make no reference to the sidebar instance, so it is GC'd
   1.862 +  let sidebar = Sidebar({
   1.863 +    id: testName,
   1.864 +    title: testName,
   1.865 +    url: url
   1.866 +  });
   1.867 +
   1.868 +  sidebar.show().then(function() {
   1.869 +    sidebar = null;
   1.870 +
   1.871 +    assert.equal(isSidebarShowing(window), true, 'the sidebar is showing');
   1.872 +
   1.873 +    let menuitemID = makeID(testName);
   1.874 +
   1.875 +    assert.ok(!!window.document.getElementById(menuitemID), 'the menuitem was found');
   1.876 +
   1.877 +    Cu.schedulePreciseGC(function() {
   1.878 +      loader.unload();
   1.879 +
   1.880 +      assert.equal(isSidebarShowing(window), false, 'the sidebar is not showing after unload');
   1.881 +      assert.ok(!window.document.getElementById(menuitemID), 'the menuitem was removed');
   1.882 +
   1.883 +      done();
   1.884 +    })
   1.885 +  }, assert.fail).then(null, assert.fail);
   1.886 +}
   1.887 +
   1.888 +exports.testGCdShowingSidebarsOnUnload = function(assert, done) {
   1.889 +  const loader = Loader(module);
   1.890 +  const { Sidebar } = loader.require('sdk/ui/sidebar');
   1.891 +  const window = getMostRecentBrowserWindow();
   1.892 +
   1.893 +  let testName = 'testGCdShowingSidebarsOnUnload';
   1.894 +  let url = 'data:text/html;charset=utf-8,'+testName;
   1.895 +
   1.896 +  assert.equal(isSidebarShowing(window), false, 'the sidebar is not showing');
   1.897 +
   1.898 +  let sidebar = Sidebar({
   1.899 +    id: testName,
   1.900 +    title: testName,
   1.901 +    url: url
   1.902 +  });
   1.903 +
   1.904 +  sidebar.on('show', function() {
   1.905 +    sidebar = null;
   1.906 +
   1.907 +    assert.equal(isSidebarShowing(window), true, 'the sidebar is showing');
   1.908 +
   1.909 +    let menuitemID = makeID(testName);
   1.910 +
   1.911 +    assert.ok(!!window.document.getElementById(menuitemID), 'the menuitem was found');
   1.912 +
   1.913 +    Cu.schedulePreciseGC(function() {
   1.914 +      assert.equal(isSidebarShowing(window), true, 'the sidebar is still showing after gc');
   1.915 +      assert.ok(!!window.document.getElementById(menuitemID), 'the menuitem was found after gc');
   1.916 +
   1.917 +      loader.unload();
   1.918 +
   1.919 +      assert.equal(isSidebarShowing(window), false, 'the sidebar is not showing after unload');
   1.920 +      assert.ok(!window.document.getElementById(menuitemID), 'the menuitem was removed');
   1.921 +
   1.922 +      done();
   1.923 +    })
   1.924 +  });
   1.925 +
   1.926 +  sidebar.show();
   1.927 +}
   1.928 +
   1.929 +exports.testDetachEventOnWindowClose = function(assert, done) {
   1.930 +  const loader = Loader(module);
   1.931 +  const { Sidebar } = loader.require('sdk/ui/sidebar');
   1.932 +  const window = getMostRecentBrowserWindow();
   1.933 +
   1.934 +  let testName = 'testDetachEventOnWindowClose';
   1.935 +  let url = 'data:text/html;charset=utf-8,' + testName;
   1.936 +
   1.937 +
   1.938 +  windowPromise(window.OpenBrowserWindow(), 'load').then(focus).then(function(window) {
   1.939 +    let sidebar = Sidebar({
   1.940 +      id: testName,
   1.941 +      title: testName,
   1.942 +      url: url,
   1.943 +      onAttach: function() {
   1.944 +        assert.pass('the attach event is fired');
   1.945 +        window.close();
   1.946 +      },
   1.947 +      onDetach: function() {
   1.948 +        assert.pass('the detach event is fired when the window showing it closes');
   1.949 +        loader.unload();
   1.950 +        done();
   1.951 +      }
   1.952 +    });
   1.953 +
   1.954 +    sidebar.show();
   1.955 +  }).then(null, assert.fail);
   1.956 +}
   1.957 +
   1.958 +exports.testHideEventOnWindowClose = function(assert, done) {
   1.959 +  const loader = Loader(module);
   1.960 +  const { Sidebar } = loader.require('sdk/ui/sidebar');
   1.961 +  const window = getMostRecentBrowserWindow();
   1.962 +
   1.963 +  let testName = 'testDetachEventOnWindowClose';
   1.964 +  let url = 'data:text/html;charset=utf-8,' + testName;
   1.965 +
   1.966 +
   1.967 +  windowPromise(window.OpenBrowserWindow(), 'load').then(focus).then(function(window) {
   1.968 +    let sidebar = Sidebar({
   1.969 +      id: testName,
   1.970 +      title: testName,
   1.971 +      url: url,
   1.972 +      onAttach: function() {
   1.973 +        assert.pass('the attach event is fired');
   1.974 +        window.close();
   1.975 +      },
   1.976 +      onHide: function() {
   1.977 +        assert.pass('the hide event is fired when the window showing it closes');
   1.978 +        loader.unload();
   1.979 +        done();
   1.980 +      }
   1.981 +    });
   1.982 +
   1.983 +    sidebar.show();
   1.984 +  }).then(null, assert.fail);
   1.985 +}
   1.986 +
   1.987 +exports.testGCdHiddenSidebarsOnUnload = function(assert, done) {
   1.988 +  const loader = Loader(module);
   1.989 +  const { Sidebar } = loader.require('sdk/ui/sidebar');
   1.990 +  const window = getMostRecentBrowserWindow();
   1.991 +
   1.992 +  let testName = 'testGCdHiddenSidebarsOnUnload';
   1.993 +  let url = 'data:text/html;charset=utf-8,'+testName;
   1.994 +
   1.995 +  assert.equal(isSidebarShowing(window), false, 'the sidebar is not showing');
   1.996 +
   1.997 +  // IMPORTANT: make no reference to the sidebar instance, so it is GC'd
   1.998 +  Sidebar({
   1.999 +    id: testName,
  1.1000 +    title: testName,
  1.1001 +    url: url
  1.1002 +  });
  1.1003 +
  1.1004 +  let menuitemID = makeID(testName);
  1.1005 +
  1.1006 +  assert.ok(!!window.document.getElementById(menuitemID), 'the menuitem was found');
  1.1007 +
  1.1008 +  Cu.schedulePreciseGC(function() {
  1.1009 +    assert.ok(!!window.document.getElementById(menuitemID), 'the menuitem was found after gc');
  1.1010 +
  1.1011 +    loader.unload();
  1.1012 +
  1.1013 +    assert.ok(!window.document.getElementById(menuitemID), 'the menuitem was removed');
  1.1014 +
  1.1015 +    done();
  1.1016 +  });
  1.1017 +}
  1.1018 +
  1.1019 +exports.testSidebarGettersAndSettersAfterDestroy = function(assert) {
  1.1020 +  const { Sidebar } = require('sdk/ui/sidebar');
  1.1021 +  let testName = 'testSidebarGettersAndSettersAfterDestroy';
  1.1022 +  let url = 'data:text/html;charset=utf-8,'+testName;
  1.1023 +
  1.1024 +  let sidebar = Sidebar({
  1.1025 +    id: testName,
  1.1026 +    title: testName,
  1.1027 +    url: url
  1.1028 +  });
  1.1029 +
  1.1030 +  sidebar.destroy();
  1.1031 +
  1.1032 +  assert.equal(sidebar.id, undefined, 'sidebar after destroy has no id');
  1.1033 +
  1.1034 +  assert.throws(() => sidebar.id = 'foo-tang',
  1.1035 +    /^setting a property that has only a getter/,
  1.1036 +    'id cannot be set at runtime');
  1.1037 +
  1.1038 +  assert.equal(sidebar.id, undefined, 'sidebar after destroy has no id');
  1.1039 +
  1.1040 +  assert.equal(sidebar.title, undefined, 'sidebar after destroy has no title');
  1.1041 +  sidebar.title = 'boo-tang';
  1.1042 +  assert.equal(sidebar.title, undefined, 'sidebar after destroy has no title');
  1.1043 +
  1.1044 +  assert.equal(sidebar.url, undefined, 'sidebar after destroy has no url');
  1.1045 +  sidebar.url = url + 'barz';
  1.1046 +  assert.equal(sidebar.url, undefined, 'sidebar after destroy has no url');
  1.1047 +}
  1.1048 +
  1.1049 +
  1.1050 +exports.testSidebarLeakCheckDestroyAfterAttach = function(assert, done) {
  1.1051 +  const { Sidebar } = require('sdk/ui/sidebar');
  1.1052 +  let testName = 'testSidebarLeakCheckDestroyAfterAttach';
  1.1053 +  let window = getMostRecentBrowserWindow();
  1.1054 +  let sidebar = Sidebar({
  1.1055 +    id: testName,
  1.1056 +    title: testName,
  1.1057 +    url: 'data:text/html;charset=utf-8,'+testName
  1.1058 +  });
  1.1059 +
  1.1060 +  sidebar.on('attach', function() {
  1.1061 +    assert.pass('the sidebar was shown');
  1.1062 +
  1.1063 +    sidebar.on('show', function() {
  1.1064 +      assert.fail('the sidebar show listener should have been removed');
  1.1065 +    });
  1.1066 +    assert.pass('added a sidebar show listener');
  1.1067 +
  1.1068 +    sidebar.on('hide', function() {
  1.1069 +      assert.fail('the sidebar hide listener should have been removed');
  1.1070 +    });
  1.1071 +    assert.pass('added a sidebar hide listener');
  1.1072 +
  1.1073 +    let panelBrowser = window.document.getElementById('sidebar').contentDocument.getElementById('web-panels-browser');
  1.1074 +    panelBrowser.contentWindow.addEventListener('unload', function onUnload() {
  1.1075 +      panelBrowser.contentWindow.removeEventListener('unload', onUnload, false);
  1.1076 +      // wait a tick..
  1.1077 +      setTimeout(function() {
  1.1078 +        assert.pass('the sidebar web panel was unloaded properly');
  1.1079 +        done();
  1.1080 +      })
  1.1081 +    }, false);
  1.1082 +
  1.1083 +    sidebar.destroy();
  1.1084 +  });
  1.1085 +
  1.1086 +  assert.pass('showing the sidebar');
  1.1087 +  sidebar.show();
  1.1088 +}
  1.1089 +
  1.1090 +exports.testSidebarLeakCheckUnloadAfterAttach = function(assert, done) {
  1.1091 +  const loader = Loader(module);
  1.1092 +  const { Sidebar } = loader.require('sdk/ui/sidebar');
  1.1093 +  let testName = 'testSidebarLeakCheckUnloadAfterAttach';
  1.1094 +  let window = getMostRecentBrowserWindow();
  1.1095 +  let sidebar = Sidebar({
  1.1096 +    id: testName,
  1.1097 +    title: testName,
  1.1098 +    url: 'data:text/html;charset=utf-8,'+testName
  1.1099 +  });
  1.1100 +
  1.1101 +  sidebar.on('attach', function() {
  1.1102 +    assert.pass('the sidebar was shown');
  1.1103 +
  1.1104 +    sidebar.on('show', function() {
  1.1105 +      assert.fail('the sidebar show listener should have been removed');
  1.1106 +    });
  1.1107 +    assert.pass('added a sidebar show listener');
  1.1108 +
  1.1109 +    sidebar.on('hide', function() {
  1.1110 +      assert.fail('the sidebar hide listener should have been removed');
  1.1111 +    });
  1.1112 +    assert.pass('added a sidebar hide listener');
  1.1113 +
  1.1114 +    let panelBrowser = window.document.getElementById('sidebar').contentDocument.getElementById('web-panels-browser');
  1.1115 +    panelBrowser.contentWindow.addEventListener('unload', function onUnload() {
  1.1116 +      panelBrowser.contentWindow.removeEventListener('unload', onUnload, false);
  1.1117 +      // wait a tick..
  1.1118 +      setTimeout(function() {
  1.1119 +        assert.pass('the sidebar web panel was unloaded properly');
  1.1120 +        done();
  1.1121 +      })
  1.1122 +    }, false);
  1.1123 +
  1.1124 +    loader.unload();
  1.1125 +  });
  1.1126 +
  1.1127 +  assert.pass('showing the sidebar');
  1.1128 +  sidebar.show();
  1.1129 +}
  1.1130 +
  1.1131 +exports.testTwoSidebarsWithSameTitleAndURL = function(assert) {
  1.1132 +  const { Sidebar } = require('sdk/ui/sidebar');
  1.1133 +  let testName = 'testTwoSidebarsWithSameTitleAndURL';
  1.1134 +
  1.1135 +  let title = testName;
  1.1136 +  let url = 'data:text/html;charset=utf-8,' + testName;
  1.1137 +
  1.1138 +  let sidebar1 = Sidebar({
  1.1139 +    id: testName + 1,
  1.1140 +    title: title,
  1.1141 +    url: url
  1.1142 +  });
  1.1143 +
  1.1144 +  assert.throws(function() {
  1.1145 +    Sidebar({
  1.1146 +      id: testName + 2,
  1.1147 +      title: title,
  1.1148 +      url: url
  1.1149 +    }).destroy();
  1.1150 +  }, /title.+url.+invalid/i, 'Creating two sidebars with the same title + url is not allowed');
  1.1151 +
  1.1152 +  let sidebar2 = Sidebar({
  1.1153 +    id: testName + 2,
  1.1154 +    title: title,
  1.1155 +    url: 'data:text/html;charset=utf-8,X'
  1.1156 +  });
  1.1157 +
  1.1158 +  assert.throws(function() {
  1.1159 +    sidebar2.url = url;
  1.1160 +  }, /title.+url.+invalid/i, 'Creating two sidebars with the same title + url is not allowed');
  1.1161 +
  1.1162 +  sidebar2.title = 'foo';
  1.1163 +  sidebar2.url = url;
  1.1164 +
  1.1165 +  assert.throws(function() {
  1.1166 +    sidebar2.title = title;
  1.1167 +  }, /title.+url.+invalid/i, 'Creating two sidebars with the same title + url is not allowed');
  1.1168 +
  1.1169 +  sidebar1.destroy();
  1.1170 +  sidebar2.destroy();
  1.1171 +}
  1.1172 +
  1.1173 +exports.testChangingURLBackToOriginalValue = function(assert) {
  1.1174 +  const { Sidebar } = require('sdk/ui/sidebar');
  1.1175 +  let testName = 'testChangingURLBackToOriginalValue';
  1.1176 +
  1.1177 +  let title = testName;
  1.1178 +  let url = 'data:text/html;charset=utf-8,' + testName;
  1.1179 +  let count = 0;
  1.1180 +
  1.1181 +  let sidebar = Sidebar({
  1.1182 +    id: testName,
  1.1183 +    title: title,
  1.1184 +    url: url
  1.1185 +  });
  1.1186 +
  1.1187 +  sidebar.url = url + 2;
  1.1188 +  assert.equal(sidebar.url, url + 2, 'the sidebar.url is correct');
  1.1189 +  sidebar.url = url;
  1.1190 +  assert.equal(sidebar.url, url, 'the sidebar.url is correct');
  1.1191 +
  1.1192 +  sidebar.title = 'foo';
  1.1193 +  assert.equal(sidebar.title, 'foo', 'the sidebar.title is correct');
  1.1194 +  sidebar.title = title;
  1.1195 +  assert.equal(sidebar.title, title, 'the sidebar.title is correct');
  1.1196 +
  1.1197 +  sidebar.destroy();
  1.1198 +
  1.1199 +  assert.pass('Changing values back to originals works');
  1.1200 +}
  1.1201 +
  1.1202 +exports.testShowToOpenXToClose = function(assert, done) {
  1.1203 +  const { Sidebar } = require('sdk/ui/sidebar');
  1.1204 +  let testName = 'testShowToOpenXToClose';
  1.1205 +
  1.1206 +  let title = testName;
  1.1207 +  let url = 'data:text/html;charset=utf-8,' + testName;
  1.1208 +  let window = getMostRecentBrowserWindow();
  1.1209 +
  1.1210 +  let sidebar = Sidebar({
  1.1211 +    id: testName,
  1.1212 +    title: testName,
  1.1213 +    url: url,
  1.1214 +    onShow: function() {
  1.1215 +      assert.ok(isChecked(menuitem), 'menuitem is checked');
  1.1216 +
  1.1217 +      let closeButton = window.document.querySelector('#sidebar-header > toolbarbutton.close-icon');
  1.1218 +      simulateCommand(closeButton);
  1.1219 +    },
  1.1220 +    onHide: function() {
  1.1221 +      assert.ok(!isChecked(menuitem), 'menuitem is not checked');
  1.1222 +
  1.1223 +      sidebar.destroy();
  1.1224 +      done();
  1.1225 +    }
  1.1226 +  });
  1.1227 +
  1.1228 +  let menuitem = window.document.getElementById(makeID(sidebar.id));
  1.1229 +
  1.1230 +  assert.ok(!isChecked(menuitem), 'menuitem is not checked');
  1.1231 +
  1.1232 +  sidebar.show();
  1.1233 +}
  1.1234 +
  1.1235 +exports.testShowToOpenMenuitemToClose = function(assert, done) {
  1.1236 +  const { Sidebar } = require('sdk/ui/sidebar');
  1.1237 +  let testName = 'testShowToOpenMenuitemToClose';
  1.1238 +
  1.1239 +  let title = testName;
  1.1240 +  let url = 'data:text/html;charset=utf-8,' + testName;
  1.1241 +  let window = getMostRecentBrowserWindow();
  1.1242 +
  1.1243 +  let sidebar = Sidebar({
  1.1244 +    id: testName,
  1.1245 +    title: testName,
  1.1246 +    url: url,
  1.1247 +    onShow: function() {
  1.1248 +      assert.ok(isChecked(menuitem), 'menuitem is checked');
  1.1249 +
  1.1250 +      simulateCommand(menuitem);
  1.1251 +    },
  1.1252 +    onHide: function() {
  1.1253 +      assert.ok(!isChecked(menuitem), 'menuitem is not checked');
  1.1254 +
  1.1255 +      sidebar.destroy();
  1.1256 +      done();
  1.1257 +    }
  1.1258 +  });
  1.1259 +
  1.1260 +  let menuitem = window.document.getElementById(makeID(sidebar.id));
  1.1261 +
  1.1262 +  assert.ok(!isChecked(menuitem), 'menuitem is not checked');
  1.1263 +
  1.1264 +  sidebar.show();
  1.1265 +}
  1.1266 +
  1.1267 +exports.testDestroyWhileNonBrowserWindowIsOpen = function(assert, done) {
  1.1268 +  const { Sidebar } = require('sdk/ui/sidebar');
  1.1269 +  let testName = 'testDestroyWhileNonBrowserWindowIsOpen';
  1.1270 +  let url = 'data:text/html;charset=utf-8,' + testName;
  1.1271 +
  1.1272 +  let sidebar = Sidebar({
  1.1273 +    id: testName,
  1.1274 +    title: testName,
  1.1275 +    url: url
  1.1276 +  });
  1.1277 +
  1.1278 +  open('chrome://browser/content/preferences/preferences.xul').then(function(window) {
  1.1279 +    try {
  1.1280 +      sidebar.show();
  1.1281 +      assert.equal(isSidebarShowing(getMostRecentBrowserWindow()), true, 'the sidebar is showing');
  1.1282 +
  1.1283 +      sidebar.destroy();
  1.1284 +
  1.1285 +      assert.pass('sidebar was destroyed while a non browser window was open');
  1.1286 +    }
  1.1287 +    catch(e) {
  1.1288 +      assert.fail(e);
  1.1289 +    }
  1.1290 +
  1.1291 +    return window;
  1.1292 +  }).then(close).then(function() {
  1.1293 +    assert.equal(isSidebarShowing(getMostRecentBrowserWindow()), false, 'the sidebar is not showing');
  1.1294 +  }).then(done, assert.fail);
  1.1295 +}
  1.1296 +
  1.1297 +exports.testEventListeners = function(assert, done) {
  1.1298 +  const { Sidebar } = require('sdk/ui/sidebar');
  1.1299 +  let testName = 'testWhatThisIsInSidebarEventListeners';
  1.1300 +  let eventListenerOrder = [];
  1.1301 +
  1.1302 +  let constructorOnShow = defer();
  1.1303 +  let constructorOnHide = defer();
  1.1304 +  let constructorOnAttach = defer();
  1.1305 +  let constructorOnReady = defer();
  1.1306 +
  1.1307 +  let onShow = defer();
  1.1308 +  let onHide = defer();
  1.1309 +  let onAttach = defer();
  1.1310 +  let onReady = defer();
  1.1311 +
  1.1312 +  let onceShow = defer();
  1.1313 +  let onceHide = defer();
  1.1314 +  let onceAttach = defer();
  1.1315 +  let onceReady = defer();
  1.1316 +
  1.1317 +  function testThis() {
  1.1318 +    assert(this, sidebar, '`this` is correct');
  1.1319 +  }
  1.1320 +
  1.1321 +  let sidebar = Sidebar({
  1.1322 +    id: testName,
  1.1323 +    title: testName,
  1.1324 +    url: 'data:text/html;charset=utf-8,' + testName,
  1.1325 +    onShow: function() {
  1.1326 +      assert.equal(this, sidebar, '`this` is correct in onShow');
  1.1327 +      eventListenerOrder.push('onShow');
  1.1328 +      constructorOnShow.resolve();
  1.1329 +    },
  1.1330 +    onAttach: function() {
  1.1331 +      assert.equal(this, sidebar, '`this` is correct in onAttach');
  1.1332 +      eventListenerOrder.push('onAttach');
  1.1333 +      constructorOnAttach.resolve();
  1.1334 +    },
  1.1335 +    onReady: function() {
  1.1336 +      assert.equal(this, sidebar, '`this` is correct in onReady');
  1.1337 +      eventListenerOrder.push('onReady');
  1.1338 +      constructorOnReady.resolve();
  1.1339 +    },
  1.1340 +    onHide: function() {
  1.1341 +      assert.equal(this, sidebar, '`this` is correct in onHide');
  1.1342 +      eventListenerOrder.push('onHide');
  1.1343 +      constructorOnHide.resolve();
  1.1344 +    }
  1.1345 +  });
  1.1346 +
  1.1347 +  sidebar.once('show', function() {
  1.1348 +    assert.equal(this, sidebar, '`this` is correct in once show');
  1.1349 +    eventListenerOrder.push('once show');
  1.1350 +    onceShow.resolve();
  1.1351 +  });
  1.1352 +  sidebar.once('attach', function() {
  1.1353 +    assert.equal(this, sidebar, '`this` is correct in once attach');
  1.1354 +    eventListenerOrder.push('once attach');
  1.1355 +    onceAttach.resolve();
  1.1356 +  });
  1.1357 +  sidebar.once('ready', function() {
  1.1358 +    assert.equal(this, sidebar, '`this` is correct in once ready');
  1.1359 +    eventListenerOrder.push('once ready');
  1.1360 +    onceReady.resolve();
  1.1361 +  });
  1.1362 +  sidebar.once('hide', function() {
  1.1363 +    assert.equal(this, sidebar, '`this` is correct in once hide');
  1.1364 +    eventListenerOrder.push('once hide');
  1.1365 +    onceHide.resolve();
  1.1366 +  });
  1.1367 +
  1.1368 +  sidebar.on('show', function() {
  1.1369 +    assert.equal(this, sidebar, '`this` is correct in on show');
  1.1370 +    eventListenerOrder.push('on show');
  1.1371 +    onShow.resolve();
  1.1372 +
  1.1373 +    sidebar.hide();
  1.1374 +  });
  1.1375 +  sidebar.on('attach', function() {
  1.1376 +    assert.equal(this, sidebar, '`this` is correct in on attach');
  1.1377 +    eventListenerOrder.push('on attach');
  1.1378 +    onAttach.resolve();
  1.1379 +  });
  1.1380 +  sidebar.on('ready', function() {
  1.1381 +    assert.equal(this, sidebar, '`this` is correct in on ready');
  1.1382 +    eventListenerOrder.push('on ready');
  1.1383 +    onReady.resolve();
  1.1384 +  });
  1.1385 +  sidebar.on('hide', function() {
  1.1386 +    assert.equal(this, sidebar, '`this` is correct in on hide');
  1.1387 +    eventListenerOrder.push('on hide');
  1.1388 +    onHide.resolve();
  1.1389 +  });
  1.1390 +
  1.1391 +  all([constructorOnShow.promise,
  1.1392 +      constructorOnAttach.promise,
  1.1393 +      constructorOnReady.promise,
  1.1394 +      constructorOnHide.promise,
  1.1395 +      onceShow.promise,
  1.1396 +      onceAttach.promise,
  1.1397 +      onceReady.promise,
  1.1398 +      onceHide.promise,
  1.1399 +      onShow.promise,
  1.1400 +      onAttach.promise,
  1.1401 +      onReady.promise,
  1.1402 +      onHide.promise]).then(function() {
  1.1403 +        assert.equal(eventListenerOrder.join(), [
  1.1404 +            'onAttach',
  1.1405 +            'once attach',
  1.1406 +            'on attach',
  1.1407 +            'onReady',
  1.1408 +            'once ready',
  1.1409 +            'on ready',
  1.1410 +            'onShow',
  1.1411 +            'once show',
  1.1412 +            'on show',
  1.1413 +            'onHide',
  1.1414 +            'once hide',
  1.1415 +            'on hide'
  1.1416 +          ].join(), 'the event order was correct');
  1.1417 +        sidebar.destroy();
  1.1418 +      }).then(done, assert.fail);
  1.1419 +
  1.1420 +  sidebar.show();
  1.1421 +}
  1.1422 +
  1.1423 +// For more information see Bug 920780
  1.1424 +exports.testAttachDoesNotEmitWhenShown = function(assert, done) {
  1.1425 +  const { Sidebar } = require('sdk/ui/sidebar');
  1.1426 +  let testName = 'testSidebarLeakCheckUnloadAfterAttach';
  1.1427 +  let count = 0;
  1.1428 +
  1.1429 +  let sidebar = Sidebar({
  1.1430 +    id: testName,
  1.1431 +    title: testName,
  1.1432 +    url: 'data:text/html;charset=utf-8,'+testName,
  1.1433 +    onAttach: function() {
  1.1434 +      if (count > 2) {
  1.1435 +        assert.fail('sidebar was attached again..');
  1.1436 +      }
  1.1437 +      else {
  1.1438 +        assert.pass('sidebar was attached ' + count + ' time(s)');
  1.1439 +      }
  1.1440 +
  1.1441 +      if (++count == 1) {
  1.1442 +        setImmediate(function() {
  1.1443 +          let shownFired = 0;
  1.1444 +          let onShow = () => shownFired++;
  1.1445 +          sidebar.on('show', onShow);
  1.1446 +
  1.1447 +          sidebar.show()
  1.1448 +          .then(() => assert.equal(shownFired, 0, 'shown should not be fired again when already showing from after attach'))
  1.1449 +          .then(sidebar.hide.bind(sidebar))
  1.1450 +          .then(sidebar.show.bind(sidebar))
  1.1451 +          .then(() => assert.equal(shownFired, 1, 'shown was emitted when `show` called after being hidden'))
  1.1452 +          .then(sidebar.show.bind(sidebar))
  1.1453 +          .then(() => {
  1.1454 +            assert.equal(shownFired, 1, 'shown was not emitted again if already being shown');
  1.1455 +            sidebar.off('show', onShow);
  1.1456 +            sidebar.destroy();
  1.1457 +          }).catch(assert.fail).then(done);
  1.1458 +        });
  1.1459 +      }
  1.1460 +    }
  1.1461 +  });
  1.1462 +
  1.1463 +  sidebar.show();
  1.1464 +}
  1.1465 +
  1.1466 +// If the module doesn't support the app we're being run in, require() will
  1.1467 +// throw.  In that case, remove all tests above from exports, and add one dummy
  1.1468 +// test that passes.
  1.1469 +try {
  1.1470 +  require('sdk/ui/sidebar');
  1.1471 +}
  1.1472 +catch (err) {
  1.1473 +  if (!/^Unsupported Application/.test(err.message))
  1.1474 +    throw err;
  1.1475 +
  1.1476 +  module.exports = {
  1.1477 +    'test Unsupported Application': assert => assert.pass(err.message)
  1.1478 +  }
  1.1479 +}
  1.1480 +
  1.1481 +require('sdk/test').run(exports);

mercurial