Thu, 15 Jan 2015 15:59:08 +0100
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 | const { isTabOpen, activateTab, openTab, |
michael@0 | 7 | closeTab, getTabURL, getWindowHoldingTab } = require('sdk/tabs/utils'); |
michael@0 | 8 | const windows = require('sdk/deprecated/window-utils'); |
michael@0 | 9 | const { LoaderWithHookedConsole } = require('sdk/test/loader'); |
michael@0 | 10 | const { setTimeout } = require('sdk/timers'); |
michael@0 | 11 | const app = require("sdk/system/xul-app"); |
michael@0 | 12 | const tabs = require('sdk/tabs'); |
michael@0 | 13 | const isAustralis = "gCustomizeMode" in windows.activeBrowserWindow; |
michael@0 | 14 | const { set: setPref, get: getPref } = require("sdk/preferences/service"); |
michael@0 | 15 | const { PrefsTarget } = require("sdk/preferences/event-target"); |
michael@0 | 16 | const { defer } = require('sdk/core/promise'); |
michael@0 | 17 | |
michael@0 | 18 | const DEPRECATE_PREF = "devtools.errorconsole.deprecation_warnings"; |
michael@0 | 19 | |
michael@0 | 20 | let uri = require('sdk/self').data.url('index.html'); |
michael@0 | 21 | |
michael@0 | 22 | function closeTabPromise(tab) { |
michael@0 | 23 | let { promise, resolve } = defer(); |
michael@0 | 24 | let url = getTabURL(tab); |
michael@0 | 25 | |
michael@0 | 26 | tabs.on('close', function onCloseTab(t) { |
michael@0 | 27 | if (t.url == url) { |
michael@0 | 28 | tabs.removeListener('close', onCloseTab); |
michael@0 | 29 | setTimeout(_ => resolve(tab)) |
michael@0 | 30 | } |
michael@0 | 31 | }); |
michael@0 | 32 | closeTab(tab); |
michael@0 | 33 | |
michael@0 | 34 | return promise; |
michael@0 | 35 | } |
michael@0 | 36 | |
michael@0 | 37 | function isChromeVisible(window) { |
michael@0 | 38 | let x = window.document.documentElement.getAttribute('disablechrome') |
michael@0 | 39 | return x !== 'true'; |
michael@0 | 40 | } |
michael@0 | 41 | |
michael@0 | 42 | // Once Bug 903018 is resolved, just move the application testing to |
michael@0 | 43 | // module.metadata.engines |
michael@0 | 44 | if (app.is('Firefox')) { |
michael@0 | 45 | |
michael@0 | 46 | exports['test add-on page deprecation message'] = function(assert, done) { |
michael@0 | 47 | let { loader, messages } = LoaderWithHookedConsole(module); |
michael@0 | 48 | |
michael@0 | 49 | loader.require('sdk/preferences/event-target').PrefsTarget({ |
michael@0 | 50 | branchName: "devtools.errorconsole." |
michael@0 | 51 | }).on("deprecation_warnings", function() { |
michael@0 | 52 | if (!getPref(DEPRECATE_PREF, false)) { |
michael@0 | 53 | return undefined; |
michael@0 | 54 | } |
michael@0 | 55 | |
michael@0 | 56 | loader.require('sdk/addon-page'); |
michael@0 | 57 | |
michael@0 | 58 | assert.equal(messages.length, 1, "only one error is dispatched"); |
michael@0 | 59 | assert.equal(messages[0].type, "error", "the console message is an error"); |
michael@0 | 60 | |
michael@0 | 61 | let msg = messages[0].msg; |
michael@0 | 62 | assert.ok(msg.indexOf("DEPRECATED") === 0, |
michael@0 | 63 | "The message is deprecation message"); |
michael@0 | 64 | |
michael@0 | 65 | loader.unload(); |
michael@0 | 66 | done(); |
michael@0 | 67 | return undefined; |
michael@0 | 68 | }); |
michael@0 | 69 | setPref(DEPRECATE_PREF, false); |
michael@0 | 70 | setPref(DEPRECATE_PREF, true); |
michael@0 | 71 | }; |
michael@0 | 72 | |
michael@0 | 73 | exports['test that add-on page has no chrome'] = function(assert, done) { |
michael@0 | 74 | let { loader } = LoaderWithHookedConsole(module); |
michael@0 | 75 | loader.require('sdk/addon-page'); |
michael@0 | 76 | |
michael@0 | 77 | let window = windows.activeBrowserWindow; |
michael@0 | 78 | let tab = openTab(window, uri); |
michael@0 | 79 | |
michael@0 | 80 | assert.ok(isChromeVisible(window), 'chrome is visible for non addon page'); |
michael@0 | 81 | |
michael@0 | 82 | // need to do this in another turn to make sure event listener |
michael@0 | 83 | // that sets property has time to do that. |
michael@0 | 84 | setTimeout(function() { |
michael@0 | 85 | activateTab(tab); |
michael@0 | 86 | |
michael@0 | 87 | assert.equal(isChromeVisible(window), app.is('Fennec') || isAustralis, |
michael@0 | 88 | 'chrome is not visible for addon page'); |
michael@0 | 89 | |
michael@0 | 90 | closeTabPromise(tab).then(function() { |
michael@0 | 91 | assert.ok(isChromeVisible(window), 'chrome is visible again'); |
michael@0 | 92 | loader.unload(); |
michael@0 | 93 | assert.ok(!isTabOpen(tab), 'add-on page tab is closed on unload'); |
michael@0 | 94 | done(); |
michael@0 | 95 | }).then(null, assert.fail); |
michael@0 | 96 | }); |
michael@0 | 97 | }; |
michael@0 | 98 | |
michael@0 | 99 | exports['test that add-on page with hash has no chrome'] = function(assert, done) { |
michael@0 | 100 | let { loader } = LoaderWithHookedConsole(module); |
michael@0 | 101 | loader.require('sdk/addon-page'); |
michael@0 | 102 | |
michael@0 | 103 | let window = windows.activeBrowserWindow; |
michael@0 | 104 | let tab = openTab(window, uri + "#foo"); |
michael@0 | 105 | |
michael@0 | 106 | assert.ok(isChromeVisible(window), 'chrome is visible for non addon page'); |
michael@0 | 107 | |
michael@0 | 108 | // need to do this in another turn to make sure event listener |
michael@0 | 109 | // that sets property has time to do that. |
michael@0 | 110 | setTimeout(function() { |
michael@0 | 111 | activateTab(tab); |
michael@0 | 112 | |
michael@0 | 113 | assert.equal(isChromeVisible(window), app.is('Fennec') || isAustralis, |
michael@0 | 114 | 'chrome is not visible for addon page'); |
michael@0 | 115 | |
michael@0 | 116 | closeTabPromise(tab).then(function() { |
michael@0 | 117 | assert.ok(isChromeVisible(window), 'chrome is visible again'); |
michael@0 | 118 | loader.unload(); |
michael@0 | 119 | assert.ok(!isTabOpen(tab), 'add-on page tab is closed on unload'); |
michael@0 | 120 | done(); |
michael@0 | 121 | }).then(null, assert.fail); |
michael@0 | 122 | }); |
michael@0 | 123 | }; |
michael@0 | 124 | |
michael@0 | 125 | exports['test that add-on page with querystring has no chrome'] = function(assert, done) { |
michael@0 | 126 | let { loader } = LoaderWithHookedConsole(module); |
michael@0 | 127 | loader.require('sdk/addon-page'); |
michael@0 | 128 | |
michael@0 | 129 | let window = windows.activeBrowserWindow; |
michael@0 | 130 | let tab = openTab(window, uri + '?foo=bar'); |
michael@0 | 131 | |
michael@0 | 132 | assert.ok(isChromeVisible(window), 'chrome is visible for non addon page'); |
michael@0 | 133 | |
michael@0 | 134 | // need to do this in another turn to make sure event listener |
michael@0 | 135 | // that sets property has time to do that. |
michael@0 | 136 | setTimeout(function() { |
michael@0 | 137 | activateTab(tab); |
michael@0 | 138 | |
michael@0 | 139 | assert.equal(isChromeVisible(window), app.is('Fennec') || isAustralis, |
michael@0 | 140 | 'chrome is not visible for addon page'); |
michael@0 | 141 | |
michael@0 | 142 | closeTabPromise(tab).then(function() { |
michael@0 | 143 | assert.ok(isChromeVisible(window), 'chrome is visible again'); |
michael@0 | 144 | loader.unload(); |
michael@0 | 145 | assert.ok(!isTabOpen(tab), 'add-on page tab is closed on unload'); |
michael@0 | 146 | done(); |
michael@0 | 147 | }).then(null, assert.fail); |
michael@0 | 148 | }); |
michael@0 | 149 | }; |
michael@0 | 150 | |
michael@0 | 151 | exports['test that add-on page with hash and querystring has no chrome'] = function(assert, done) { |
michael@0 | 152 | let { loader } = LoaderWithHookedConsole(module); |
michael@0 | 153 | loader.require('sdk/addon-page'); |
michael@0 | 154 | |
michael@0 | 155 | let window = windows.activeBrowserWindow; |
michael@0 | 156 | let tab = openTab(window, uri + '#foo?foo=bar'); |
michael@0 | 157 | |
michael@0 | 158 | assert.ok(isChromeVisible(window), 'chrome is visible for non addon page'); |
michael@0 | 159 | |
michael@0 | 160 | // need to do this in another turn to make sure event listener |
michael@0 | 161 | // that sets property has time to do that. |
michael@0 | 162 | setTimeout(function() { |
michael@0 | 163 | activateTab(tab); |
michael@0 | 164 | |
michael@0 | 165 | assert.equal(isChromeVisible(window), app.is('Fennec') || isAustralis, |
michael@0 | 166 | 'chrome is not visible for addon page'); |
michael@0 | 167 | |
michael@0 | 168 | closeTabPromise(tab).then(function() { |
michael@0 | 169 | assert.ok(isChromeVisible(window), 'chrome is visible again'); |
michael@0 | 170 | loader.unload(); |
michael@0 | 171 | assert.ok(!isTabOpen(tab), 'add-on page tab is closed on unload'); |
michael@0 | 172 | done(); |
michael@0 | 173 | }).then(null, assert.fail); |
michael@0 | 174 | }); |
michael@0 | 175 | }; |
michael@0 | 176 | |
michael@0 | 177 | exports['test that malformed uri is not an addon-page'] = function(assert, done) { |
michael@0 | 178 | let { loader } = LoaderWithHookedConsole(module); |
michael@0 | 179 | loader.require('sdk/addon-page'); |
michael@0 | 180 | |
michael@0 | 181 | let window = windows.activeBrowserWindow; |
michael@0 | 182 | let tab = openTab(window, uri + 'anguage'); |
michael@0 | 183 | |
michael@0 | 184 | // need to do this in another turn to make sure event listener |
michael@0 | 185 | // that sets property has time to do that. |
michael@0 | 186 | setTimeout(function() { |
michael@0 | 187 | activateTab(tab); |
michael@0 | 188 | |
michael@0 | 189 | assert.ok(isChromeVisible(window), 'chrome is visible for malformed uri'); |
michael@0 | 190 | |
michael@0 | 191 | closeTabPromise(tab).then(function() { |
michael@0 | 192 | loader.unload(); |
michael@0 | 193 | done(); |
michael@0 | 194 | }).then(null, assert.fail); |
michael@0 | 195 | }); |
michael@0 | 196 | }; |
michael@0 | 197 | |
michael@0 | 198 | } else { |
michael@0 | 199 | exports['test unsupported'] = (assert) => assert.pass('This application is unsupported.'); |
michael@0 | 200 | } |
michael@0 | 201 | |
michael@0 | 202 | require('sdk/test/runner').runTestsFromModule(module); |