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

Thu, 15 Jan 2015 15:59:08 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 15:59:08 +0100
branch
TOR_BUG_9701
changeset 10
ac0c01689b40
permissions
-rw-r--r--

Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

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 { Toolbar } = require("sdk/ui/toolbar");
michael@0 13 const { Loader } = require("sdk/test/loader");
michael@0 14 const { identify } = require("sdk/ui/id");
michael@0 15 const { getMostRecentBrowserWindow, open, getOuterId } = require("sdk/window/utils");
michael@0 16 const { ready, close } = require("sdk/window/helpers");
michael@0 17 const { defer } = require("sdk/core/promise");
michael@0 18 const { send, stop, Reactor } = require("sdk/event/utils");
michael@0 19 const { object } = require("sdk/util/sequence");
michael@0 20 const { CustomizationInput } = require("sdk/input/customizable-ui");
michael@0 21 const { OutputPort } = require("sdk/output/system");
michael@0 22 const output = new OutputPort({ id: "toolbar-change" });
michael@0 23
michael@0 24 const wait = (toolbar, event) => {
michael@0 25 let { promise, resolve } = defer();
michael@0 26 toolbar.once(event, resolve);
michael@0 27 return promise;
michael@0 28 };
michael@0 29
michael@0 30 const show = ({id}) => send(output, object([id, {collapsed: false}]));
michael@0 31 const hide = ({id}) => send(output, object([id, {collapsed: true}]));
michael@0 32 const retitle = ({id}, title) => send(output, object([id, {title: title}]));
michael@0 33
michael@0 34 const isAttached = ({id}, window=getMostRecentBrowserWindow()) =>
michael@0 35 !!window.document.getElementById(id);
michael@0 36
michael@0 37 const isCollapsed = ({id}, window=getMostRecentBrowserWindow()) =>
michael@0 38 window.document.getElementById(id).getAttribute("collapsed") === "true";
michael@0 39
michael@0 40 const closeViaButton = ({id}, window=getMostRecentBrowserWindow()) =>
michael@0 41 window.document.getElementById("close-" + id).click();
michael@0 42
michael@0 43 const readTitle = ({id}, window=getMostRecentBrowserWindow()) =>
michael@0 44 window.document.getElementById(id).getAttribute("toolbarname");
michael@0 45
michael@0 46 exports["test toolbar API"] = function*(assert) {
michael@0 47 assert.throws(() => new Toolbar(),
michael@0 48 /The `option.title`/,
michael@0 49 "toolbar requires title");
michael@0 50
michael@0 51 assert.throws(() => new Toolbar({ hidden: false }),
michael@0 52 /The `option.title`/,
michael@0 53 "toolbar requires title");
michael@0 54
michael@0 55 const t1 = new Toolbar({ title: "foo" });
michael@0 56
michael@0 57 assert.throws(() => new Toolbar({ title: "foo" }),
michael@0 58 /already exists/,
michael@0 59 "can't create identical toolbars");
michael@0 60
michael@0 61 assert.ok(t1.id, "toolbar has an id");
michael@0 62 assert.equal(t1.id, identify(t1), "identify returns toolbar id");
michael@0 63 assert.deepEqual(t1.items, [], "toolbar items are empty");
michael@0 64 assert.equal(t1.title, void(0), "title is void until attached");
michael@0 65 assert.equal(t1.hidden, void(0), "hidden is void until attached");
michael@0 66
michael@0 67 yield wait(t1, "attach");
michael@0 68
michael@0 69 assert.equal(t1.title, "foo", "title is set after attach");
michael@0 70 assert.equal(t1.hidden, false, "by default toolbar isn't hidden");
michael@0 71
michael@0 72 assert.throws(() => new Toolbar({ title: "foo" }),
michael@0 73 /already exists/,
michael@0 74 "still can't create identical toolbar");
michael@0 75
michael@0 76
michael@0 77 const t2 = new Toolbar({ title: "bar", hidden: true });
michael@0 78 assert.pass("can create different toolbar though");
michael@0 79
michael@0 80 assert.ok(t2.id, "toolbar has an id");
michael@0 81 assert.equal(t2.id, identify(t2), "identify returns toolbar id");
michael@0 82 assert.notEqual(t2.id, t1.id, "each toolbar has unique id");
michael@0 83
michael@0 84 yield wait(t2, "attach");
michael@0 85
michael@0 86 assert.equal(t2.title, "bar", "title is set after attach");
michael@0 87 assert.equal(t2.hidden, true, "toolbar is hidden as specified");
michael@0 88
michael@0 89 t2.destroy();
michael@0 90 t1.destroy();
michael@0 91
michael@0 92 yield wait(t1, "detach");
michael@0 93
michael@0 94 assert.equal(t1.title, void(0), "title is voided after detach");
michael@0 95 assert.equal(t1.hidden, void(0), "hidden is void fater detach");
michael@0 96
michael@0 97
michael@0 98 const t3 = new Toolbar({ title: "foo" });
michael@0 99 assert.pass("Can create toolbar after identical was detached");
michael@0 100
michael@0 101 assert.equal(t3.id, t1.id, "toolbar has a same id");
michael@0 102 assert.equal(t3.id, identify(t3), "identify returns toolbar.id");
michael@0 103 assert.equal(t3.title, void(0), "title is void before attach");
michael@0 104 assert.equal(t3.hidden, void(0), "hidden is void before attach");
michael@0 105
michael@0 106 yield wait(t3, "attach");
michael@0 107
michael@0 108 assert.equal(t3.title, "foo", "title is set");
michael@0 109 assert.equal(t3.hidden, false, "toolbar is hidden");
michael@0 110
michael@0 111 t3.destroy();
michael@0 112
michael@0 113 yield wait(t3, "detach");
michael@0 114 };
michael@0 115
michael@0 116 exports["test show / hide toolbar"] = function*(assert) {
michael@0 117 const t1 = new Toolbar({ title: "foo" });
michael@0 118
michael@0 119 yield wait(t1, "attach");
michael@0 120
michael@0 121 assert.equal(t1.title, "foo", "title is set after attach");
michael@0 122 assert.equal(t1.hidden, false, "by default toolbar isn't hidden");
michael@0 123 assert.ok(isAttached(t1), "toolbar was actually attarched");
michael@0 124 assert.ok(!isCollapsed(t1), "toolbar isn't collapsed");
michael@0 125
michael@0 126 hide(t1);
michael@0 127 assert.equal(t1.hidden, false, "not hidden yet");
michael@0 128
michael@0 129 yield wait(t1, "hide");
michael@0 130 assert.equal(t1.hidden, true, "toolbar got hidden");
michael@0 131 assert.ok(isCollapsed(t1), "toolbar is collapsed");
michael@0 132
michael@0 133 show(t1);
michael@0 134
michael@0 135 yield wait(t1, "show");
michael@0 136 assert.equal(t1.hidden, false, "toolbar got shown");
michael@0 137 assert.ok(!isCollapsed(t1), "toolbar isn't collapsed");
michael@0 138
michael@0 139 t1.destroy();
michael@0 140 yield wait(t1, "detach");
michael@0 141 assert.ok(!isAttached(t1), "toolbar is no longer attached");
michael@0 142 };
michael@0 143
michael@0 144 exports["test multiple windows & toolbars"] = function*(assert) {
michael@0 145 const w1 = getMostRecentBrowserWindow();
michael@0 146 const t1 = new Toolbar({ title: "multi window" });
michael@0 147
michael@0 148 yield wait(t1, "attach");
michael@0 149
michael@0 150 assert.equal(t1.title, "multi window", "title is set after attach");
michael@0 151 assert.equal(t1.hidden, false, "by default toolbar isn't hidden");
michael@0 152 assert.ok(isAttached(t1, w1), "toolbar was actually attarched");
michael@0 153 assert.ok(!isCollapsed(t1, w1), "toolbar isn't collapsed");
michael@0 154
michael@0 155 const w2 = open();
michael@0 156 yield ready(w2);
michael@0 157
michael@0 158 assert.ok(isAttached(t1, w2), "toolbar was attached to second window");
michael@0 159 assert.ok(!isCollapsed(t1, w2), "toolbar isn't collabsed");
michael@0 160
michael@0 161 hide(t1);
michael@0 162 yield wait(t1, "hide");
michael@0 163
michael@0 164 assert.ok(isCollapsed(t1, w1) && isCollapsed(t1, w2),
michael@0 165 "toolbar is collabsed");
michael@0 166
michael@0 167
michael@0 168 const w3 = open();
michael@0 169 yield ready(w3);
michael@0 170
michael@0 171 assert.ok(isAttached(t1, w1) && isAttached(t1, w2) && isAttached(t1, w3),
michael@0 172 "toolbar is attached to all windows");
michael@0 173 assert.ok(isCollapsed(t1, w3) && isCollapsed(t1, w3) && isCollapsed(t1, w3),
michael@0 174 "toolbar still collapsed in all windows");
michael@0 175
michael@0 176
michael@0 177 const t2 = new Toolbar({ title: "multi hidden", hidden: true });
michael@0 178
michael@0 179 yield wait(t2, "attach");
michael@0 180
michael@0 181 assert.equal(t2.title, "multi hidden", "title is set after attach");
michael@0 182 assert.equal(t2.hidden, true, "isn't hidden as specified");
michael@0 183
michael@0 184 assert.ok(isAttached(t1, w1) && isAttached(t1, w2) && isAttached(t1, w3),
michael@0 185 "toolbar#1 is still attached");
michael@0 186 assert.ok(isAttached(t2, w1) && isAttached(t2, w2) && isAttached(t2, w3),
michael@0 187 "toolbar#2 was attached to all windows");
michael@0 188
michael@0 189 assert.ok(isCollapsed(t1, w1) && isCollapsed(t1, w2) && isCollapsed(t1, w3),
michael@0 190 "toolbar#1 is still collapsed");
michael@0 191
michael@0 192 assert.ok(isCollapsed(t2, w1) && isCollapsed(t2, w2) && isCollapsed(t2, w3),
michael@0 193 "toolbar#2 is collapsed");
michael@0 194
michael@0 195 t1.destroy();
michael@0 196 yield wait(t1, "detach");
michael@0 197
michael@0 198 assert.ok(!isAttached(t1, w1) && !isAttached(t1, w2) && !isAttached(t1, w3),
michael@0 199 "toolbar#1 was detached from all windows");
michael@0 200 assert.ok(isAttached(t2, w1) && isAttached(t2, w2) && isAttached(t2, w3),
michael@0 201 "toolbar#2 is still attached to all windows");
michael@0 202
michael@0 203 yield close(w2);
michael@0 204
michael@0 205 assert.ok(isAttached(t2, w1) && isAttached(t2, w3),
michael@0 206 "toolbar#2 is still attached to remaining windows");
michael@0 207 assert.ok(isCollapsed(t2, w1) && isCollapsed(t2, w3),
michael@0 208 "toolbar#2 is still collapsed");
michael@0 209
michael@0 210 show(t2);
michael@0 211 yield wait(t2, "show");
michael@0 212
michael@0 213 assert.ok(!isCollapsed(t2, w1) && !isCollapsed(t2, w3),
michael@0 214 "toolbar#2 is not collapsed");
michael@0 215
michael@0 216 yield close(w3);
michael@0 217
michael@0 218 assert.ok(isAttached(t2, w1), "still attached to last window");
michael@0 219 assert.ok(!isCollapsed(t2, w1), "still isn't collapsed");
michael@0 220
michael@0 221 t2.destroy();
michael@0 222 yield wait(t2, "detach");
michael@0 223
michael@0 224 assert.ok(!isAttached(t2, w1), "toolbar was removed");
michael@0 225 };
michael@0 226
michael@0 227 exports["test toolbar persistence"] = function*(assert) {
michael@0 228 const t1 = new Toolbar({ title: "per sist ence" });
michael@0 229
michael@0 230 yield wait(t1, "attach");
michael@0 231
michael@0 232 assert.equal(t1.hidden, false, "toolbar is visible");
michael@0 233
michael@0 234 hide(t1);
michael@0 235 yield wait(t1, "hide");
michael@0 236
michael@0 237 assert.equal(t1.hidden, true, "toolbar is hidden");
michael@0 238 assert.ok(isCollapsed(t1), "toolbar is collapsed");
michael@0 239
michael@0 240 t1.destroy();
michael@0 241
michael@0 242 yield wait(t1, "detach");
michael@0 243
michael@0 244 const t2 = new Toolbar({ title: "per sist ence" });
michael@0 245
michael@0 246 yield wait(t2, "attach");
michael@0 247
michael@0 248 assert.equal(t2.hidden, true, "toolbar persisted state");
michael@0 249 assert.ok(isCollapsed(t2), "toolbar is collapsed");
michael@0 250
michael@0 251 show(t2);
michael@0 252 t2.destroy();
michael@0 253
michael@0 254 yield wait(t2, "detach");
michael@0 255
michael@0 256 const t3 = new Toolbar({ title: "per sist ence", hidden: true });
michael@0 257
michael@0 258 yield wait(t3, "attach");
michael@0 259
michael@0 260 assert.equal(t3.hidden, false, "toolbar persisted state & ignored option");
michael@0 261 assert.ok(!isCollapsed(t3), "toolbar isn1t collapsed");
michael@0 262
michael@0 263 t3.destroy();
michael@0 264
michael@0 265 yield wait(t3, "detach");
michael@0 266 };
michael@0 267
michael@0 268
michael@0 269 exports["test toolbar unload"] = function*(assert) {
michael@0 270 // We override add-on id, otherwise two instances of Toolbar host (view.js)
michael@0 271 // handling same updates, cause message port is bound to add-on id.
michael@0 272 const loader = Loader(module, null, null, {id: "toolbar-unload-addon"});
michael@0 273 const { Toolbar } = loader.require("sdk/ui/toolbar");
michael@0 274
michael@0 275 const w1 = getMostRecentBrowserWindow();
michael@0 276 const w2 = open();
michael@0 277
michael@0 278 yield ready(w2);
michael@0 279
michael@0 280 const t1 = new Toolbar({ title: "unload" });
michael@0 281
michael@0 282 yield wait(t1, "attach");
michael@0 283
michael@0 284 assert.ok(isAttached(t1, w1) && isAttached(t1, w2),
michael@0 285 "attached to both windows");
michael@0 286
michael@0 287
michael@0 288 loader.unload();
michael@0 289
michael@0 290
michael@0 291 assert.ok(!isAttached(t1, w1) && !isAttached(t1, w2),
michael@0 292 "detached from both windows on unload");
michael@0 293
michael@0 294 yield close(w2);
michael@0 295 };
michael@0 296
michael@0 297 exports["test toolbar close button"] = function*(assert) {
michael@0 298 const t1 = new Toolbar({ title: "close with button" });
michael@0 299
michael@0 300 yield wait(t1, "attach");
michael@0 301 const w1 = getMostRecentBrowserWindow();
michael@0 302 const w2 = open();
michael@0 303
michael@0 304 yield ready(w2);
michael@0 305
michael@0 306 assert.ok(!isCollapsed(t1, w1) && !isCollapsed(t1, w2),
michael@0 307 "toolbar isn't collapsed");
michael@0 308
michael@0 309 closeViaButton(t1);
michael@0 310
michael@0 311 yield wait(t1, "hide");
michael@0 312
michael@0 313 assert.ok(isCollapsed(t1, w1) && isCollapsed(t1, w2),
michael@0 314 "toolbar was collapsed");
michael@0 315
michael@0 316 t1.destroy();
michael@0 317 yield wait(t1, "detach");
michael@0 318 yield close(w2);
michael@0 319 };
michael@0 320
michael@0 321 exports["test title change"] = function*(assert) {
michael@0 322 const w1 = getMostRecentBrowserWindow();
michael@0 323 const w2 = open();
michael@0 324
michael@0 325 yield ready(w2);
michael@0 326
michael@0 327 const t1 = new Toolbar({ title: "first title" });
michael@0 328 const id = t1.id;
michael@0 329
michael@0 330 yield wait(t1, "attach");
michael@0 331
michael@0 332
michael@0 333 assert.equal(t1.title, "first title",
michael@0 334 "correct title is set");
michael@0 335 assert.equal(readTitle(t1, w1), "first title",
michael@0 336 "title set in the view of first window");
michael@0 337 assert.equal(readTitle(t1, w2), "first title",
michael@0 338 "title set in the view of second window");
michael@0 339
michael@0 340 retitle(t1, "second title");
michael@0 341
michael@0 342 // Hide & show so to make sure changes go through a round
michael@0 343 // loop.
michael@0 344 hide(t1);
michael@0 345 yield wait(t1, "hide");
michael@0 346 show(t1);
michael@0 347 yield wait(t1, "show");
michael@0 348
michael@0 349 assert.equal(t1.id, id, "id remains same");
michael@0 350 assert.equal(t1.title, "second title", "instance title was updated");
michael@0 351 assert.equal(readTitle(t1, w1), "second title",
michael@0 352 "title updated in first window");
michael@0 353 assert.equal(readTitle(t1, w2), "second title",
michael@0 354 "title updated in second window");
michael@0 355
michael@0 356 t1.destroy();
michael@0 357 yield wait(t1, "detach");
michael@0 358 yield close(w2);
michael@0 359 };
michael@0 360
michael@0 361 exports["test toolbar is not customizable"] = function*(assert, done) {
michael@0 362 const { window, document, gCustomizeMode } = getMostRecentBrowserWindow();
michael@0 363 const outerId = getOuterId(window);
michael@0 364 const input = new CustomizationInput();
michael@0 365 const customized = defer();
michael@0 366 const customizedEnd = defer();
michael@0 367
michael@0 368 new Reactor({ onStep: value => {
michael@0 369 if (value[outerId] === true)
michael@0 370 customized.resolve();
michael@0 371 if (value[outerId] === null)
michael@0 372 customizedEnd.resolve();
michael@0 373 }}).run(input);
michael@0 374
michael@0 375 const toolbar = new Toolbar({ title: "foo" });
michael@0 376
michael@0 377 yield wait(toolbar, "attach");
michael@0 378
michael@0 379 let view = document.getElementById(toolbar.id);
michael@0 380 let label = view.querySelector("label");
michael@0 381 let inner = view.querySelector("toolbar");
michael@0 382
michael@0 383 assert.equal(view.getAttribute("customizable"), "false",
michael@0 384 "The outer toolbar is not customizable.");
michael@0 385
michael@0 386 assert.ok(label.collapsed,
michael@0 387 "The label is not displayed.")
michael@0 388
michael@0 389 assert.equal(inner.getAttribute("customizable"), "true",
michael@0 390 "The inner toolbar is customizable.");
michael@0 391
michael@0 392 assert.equal(window.getComputedStyle(inner).visibility, "visible",
michael@0 393 "The inner toolbar is visible.");
michael@0 394
michael@0 395 // Enter in customization mode
michael@0 396 gCustomizeMode.toggle();
michael@0 397
michael@0 398 yield customized.promise;
michael@0 399
michael@0 400 assert.equal(view.getAttribute("customizable"), "false",
michael@0 401 "The outer toolbar is not customizable.");
michael@0 402
michael@0 403 assert.equal(label.collapsed, false,
michael@0 404 "The label is displayed.")
michael@0 405
michael@0 406 assert.equal(inner.getAttribute("customizable"), "true",
michael@0 407 "The inner toolbar is customizable.");
michael@0 408
michael@0 409 assert.equal(window.getComputedStyle(inner).visibility, "hidden",
michael@0 410 "The inner toolbar is hidden.");
michael@0 411
michael@0 412 // Exit from customization mode
michael@0 413 gCustomizeMode.toggle();
michael@0 414
michael@0 415 yield customizedEnd.promise;
michael@0 416
michael@0 417 assert.equal(view.getAttribute("customizable"), "false",
michael@0 418 "The outer toolbar is not customizable.");
michael@0 419
michael@0 420 assert.ok(label.collapsed,
michael@0 421 "The label is not displayed.")
michael@0 422
michael@0 423 assert.equal(inner.getAttribute("customizable"), "true",
michael@0 424 "The inner toolbar is customizable.");
michael@0 425
michael@0 426 assert.equal(window.getComputedStyle(inner).visibility, "visible",
michael@0 427 "The inner toolbar is visible.");
michael@0 428
michael@0 429 toolbar.destroy();
michael@0 430 };
michael@0 431
michael@0 432 exports["test button are attached to toolbar"] = function*(assert) {
michael@0 433 const { document } = getMostRecentBrowserWindow();
michael@0 434 const { ActionButton, ToggleButton } = require("sdk/ui");
michael@0 435 const { identify } = require("sdk/ui/id");
michael@0 436
michael@0 437 let action = ActionButton({
michael@0 438 id: "btn-1",
michael@0 439 label: "action",
michael@0 440 icon: "./placeholder.png"
michael@0 441 });
michael@0 442
michael@0 443 let toggle = ToggleButton({
michael@0 444 id: "btn-2",
michael@0 445 label: "toggle",
michael@0 446 icon: "./placeholder.png"
michael@0 447 });
michael@0 448
michael@0 449 const toolbar = new Toolbar({
michael@0 450 title: "foo",
michael@0 451 items: [action, toggle]
michael@0 452 });
michael@0 453
michael@0 454 yield wait(toolbar, "attach");
michael@0 455
michael@0 456 let actionNode = document.getElementById(identify(action));
michael@0 457 let toggleNode = document.getElementById(identify(toggle));
michael@0 458
michael@0 459 assert.notEqual(actionNode, null,
michael@0 460 "action button exists in the document");
michael@0 461
michael@0 462 assert.notEqual(actionNode, null,
michael@0 463 "action button exists in the document");
michael@0 464
michael@0 465 assert.notEqual(toggleNode, null,
michael@0 466 "toggle button exists in the document");
michael@0 467
michael@0 468 assert.equal(actionNode.nextElementSibling, toggleNode,
michael@0 469 "action button is placed before toggle button");
michael@0 470
michael@0 471 assert.equal(actionNode.parentNode.parentNode.id, toolbar.id,
michael@0 472 "buttons are placed in the correct toolbar");
michael@0 473
michael@0 474 toolbar.destroy();
michael@0 475 };
michael@0 476
michael@0 477 require("sdk/test").run(exports);

mercurial