Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
michael@0 | 1 | /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
michael@0 | 2 | /* vim:set ts=2 sw=2 sts=2 et: */ |
michael@0 | 3 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 4 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 5 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 6 | |
michael@0 | 7 | /** |
michael@0 | 8 | * Tests the sanitize dialog (a.k.a. the clear recent history dialog). |
michael@0 | 9 | * See bug 480169. |
michael@0 | 10 | * |
michael@0 | 11 | * The purpose of this test is not to fully flex the sanitize timespan code; |
michael@0 | 12 | * browser/base/content/test/general/browser_sanitize-timespans.js does that. This |
michael@0 | 13 | * test checks the UI of the dialog and makes sure it's correctly connected to |
michael@0 | 14 | * the sanitize timespan code. |
michael@0 | 15 | * |
michael@0 | 16 | * Some of this code, especially the history creation parts, was taken from |
michael@0 | 17 | * browser/base/content/test/general/browser_sanitize-timespans.js. |
michael@0 | 18 | */ |
michael@0 | 19 | |
michael@0 | 20 | Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); |
michael@0 | 21 | |
michael@0 | 22 | XPCOMUtils.defineLazyModuleGetter(this, "FormHistory", |
michael@0 | 23 | "resource://gre/modules/FormHistory.jsm"); |
michael@0 | 24 | XPCOMUtils.defineLazyModuleGetter(this, "Downloads", |
michael@0 | 25 | "resource://gre/modules/Downloads.jsm"); |
michael@0 | 26 | |
michael@0 | 27 | let tempScope = {}; |
michael@0 | 28 | Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader) |
michael@0 | 29 | .loadSubScript("chrome://browser/content/sanitize.js", tempScope); |
michael@0 | 30 | let Sanitizer = tempScope.Sanitizer; |
michael@0 | 31 | |
michael@0 | 32 | const kMsecPerMin = 60 * 1000; |
michael@0 | 33 | const kUsecPerMin = 60 * 1000000; |
michael@0 | 34 | |
michael@0 | 35 | let formEntries, downloadIDs, olderDownloadIDs; |
michael@0 | 36 | |
michael@0 | 37 | // Add tests here. Each is a function that's called by doNextTest(). |
michael@0 | 38 | var gAllTests = [ |
michael@0 | 39 | |
michael@0 | 40 | /** |
michael@0 | 41 | * Initializes the dialog to its default state. |
michael@0 | 42 | */ |
michael@0 | 43 | function () { |
michael@0 | 44 | let wh = new WindowHelper(); |
michael@0 | 45 | wh.onload = function () { |
michael@0 | 46 | // Select "Last Hour" |
michael@0 | 47 | this.selectDuration(Sanitizer.TIMESPAN_HOUR); |
michael@0 | 48 | // Hide details |
michael@0 | 49 | if (!this.getItemList().collapsed) |
michael@0 | 50 | this.toggleDetails(); |
michael@0 | 51 | this.acceptDialog(); |
michael@0 | 52 | }; |
michael@0 | 53 | wh.open(); |
michael@0 | 54 | }, |
michael@0 | 55 | |
michael@0 | 56 | /** |
michael@0 | 57 | * Cancels the dialog, makes sure history not cleared. |
michael@0 | 58 | */ |
michael@0 | 59 | function () { |
michael@0 | 60 | // Add history (within the past hour) |
michael@0 | 61 | let uris = []; |
michael@0 | 62 | let places = []; |
michael@0 | 63 | let pURI; |
michael@0 | 64 | for (let i = 0; i < 30; i++) { |
michael@0 | 65 | pURI = makeURI("http://" + i + "-minutes-ago.com/"); |
michael@0 | 66 | places.push({uri: pURI, visitDate: visitTimeForMinutesAgo(i)}); |
michael@0 | 67 | uris.push(pURI); |
michael@0 | 68 | } |
michael@0 | 69 | |
michael@0 | 70 | addVisits(places, function() { |
michael@0 | 71 | let wh = new WindowHelper(); |
michael@0 | 72 | wh.onload = function () { |
michael@0 | 73 | this.selectDuration(Sanitizer.TIMESPAN_HOUR); |
michael@0 | 74 | this.checkPrefCheckbox("history", false); |
michael@0 | 75 | this.checkDetails(false); |
michael@0 | 76 | |
michael@0 | 77 | // Show details |
michael@0 | 78 | this.toggleDetails(); |
michael@0 | 79 | this.checkDetails(true); |
michael@0 | 80 | |
michael@0 | 81 | // Hide details |
michael@0 | 82 | this.toggleDetails(); |
michael@0 | 83 | this.checkDetails(false); |
michael@0 | 84 | this.cancelDialog(); |
michael@0 | 85 | }; |
michael@0 | 86 | wh.onunload = function () { |
michael@0 | 87 | yield promiseHistoryClearedState(uris, false); |
michael@0 | 88 | yield blankSlate(); |
michael@0 | 89 | yield promiseHistoryClearedState(uris, true); |
michael@0 | 90 | }; |
michael@0 | 91 | wh.open(); |
michael@0 | 92 | }); |
michael@0 | 93 | }, |
michael@0 | 94 | |
michael@0 | 95 | function () { |
michael@0 | 96 | // Add downloads (within the past hour). |
michael@0 | 97 | Task.spawn(function () { |
michael@0 | 98 | downloadIDs = []; |
michael@0 | 99 | for (let i = 0; i < 5; i++) { |
michael@0 | 100 | yield addDownloadWithMinutesAgo(downloadIDs, i); |
michael@0 | 101 | } |
michael@0 | 102 | // Add downloads (over an hour ago). |
michael@0 | 103 | olderDownloadIDs = []; |
michael@0 | 104 | for (let i = 0; i < 5; i++) { |
michael@0 | 105 | yield addDownloadWithMinutesAgo(olderDownloadIDs, 61 + i); |
michael@0 | 106 | } |
michael@0 | 107 | |
michael@0 | 108 | doNextTest(); |
michael@0 | 109 | }).then(null, Components.utils.reportError); |
michael@0 | 110 | }, |
michael@0 | 111 | |
michael@0 | 112 | /** |
michael@0 | 113 | * Ensures that the combined history-downloads checkbox clears both history |
michael@0 | 114 | * visits and downloads when checked; the dialog respects simple timespan. |
michael@0 | 115 | */ |
michael@0 | 116 | function () { |
michael@0 | 117 | // Add history (within the past hour). |
michael@0 | 118 | let uris = []; |
michael@0 | 119 | let places = []; |
michael@0 | 120 | let pURI; |
michael@0 | 121 | for (let i = 0; i < 30; i++) { |
michael@0 | 122 | pURI = makeURI("http://" + i + "-minutes-ago.com/"); |
michael@0 | 123 | places.push({uri: pURI, visitDate: visitTimeForMinutesAgo(i)}); |
michael@0 | 124 | uris.push(pURI); |
michael@0 | 125 | } |
michael@0 | 126 | // Add history (over an hour ago). |
michael@0 | 127 | let olderURIs = []; |
michael@0 | 128 | for (let i = 0; i < 5; i++) { |
michael@0 | 129 | pURI = makeURI("http://" + (61 + i) + "-minutes-ago.com/"); |
michael@0 | 130 | places.push({uri: pURI, visitDate: visitTimeForMinutesAgo(61 + i)}); |
michael@0 | 131 | olderURIs.push(pURI); |
michael@0 | 132 | } |
michael@0 | 133 | |
michael@0 | 134 | addVisits(places, function() { |
michael@0 | 135 | let totalHistoryVisits = uris.length + olderURIs.length; |
michael@0 | 136 | |
michael@0 | 137 | let wh = new WindowHelper(); |
michael@0 | 138 | wh.onload = function () { |
michael@0 | 139 | this.selectDuration(Sanitizer.TIMESPAN_HOUR); |
michael@0 | 140 | this.checkPrefCheckbox("history", true); |
michael@0 | 141 | this.acceptDialog(); |
michael@0 | 142 | }; |
michael@0 | 143 | wh.onunload = function () { |
michael@0 | 144 | intPrefIs("sanitize.timeSpan", Sanitizer.TIMESPAN_HOUR, |
michael@0 | 145 | "timeSpan pref should be hour after accepting dialog with " + |
michael@0 | 146 | "hour selected"); |
michael@0 | 147 | boolPrefIs("cpd.history", true, |
michael@0 | 148 | "history pref should be true after accepting dialog with " + |
michael@0 | 149 | "history checkbox checked"); |
michael@0 | 150 | boolPrefIs("cpd.downloads", true, |
michael@0 | 151 | "downloads pref should be true after accepting dialog with " + |
michael@0 | 152 | "history checkbox checked"); |
michael@0 | 153 | |
michael@0 | 154 | // History visits and downloads within one hour should be cleared. |
michael@0 | 155 | yield promiseHistoryClearedState(uris, true); |
michael@0 | 156 | yield ensureDownloadsClearedState(downloadIDs, true); |
michael@0 | 157 | |
michael@0 | 158 | // Visits and downloads > 1 hour should still exist. |
michael@0 | 159 | yield promiseHistoryClearedState(olderURIs, false); |
michael@0 | 160 | yield ensureDownloadsClearedState(olderDownloadIDs, false); |
michael@0 | 161 | |
michael@0 | 162 | // OK, done, cleanup after ourselves. |
michael@0 | 163 | yield blankSlate(); |
michael@0 | 164 | yield promiseHistoryClearedState(olderURIs, true); |
michael@0 | 165 | yield ensureDownloadsClearedState(olderDownloadIDs, true); |
michael@0 | 166 | }; |
michael@0 | 167 | wh.open(); |
michael@0 | 168 | }); |
michael@0 | 169 | }, |
michael@0 | 170 | |
michael@0 | 171 | /** |
michael@0 | 172 | * Add form history entries for the next test. |
michael@0 | 173 | */ |
michael@0 | 174 | function () { |
michael@0 | 175 | formEntries = []; |
michael@0 | 176 | |
michael@0 | 177 | let iter = function() { |
michael@0 | 178 | for (let i = 0; i < 5; i++) { |
michael@0 | 179 | formEntries.push(addFormEntryWithMinutesAgo(iter, i)); |
michael@0 | 180 | yield undefined; |
michael@0 | 181 | } |
michael@0 | 182 | doNextTest(); |
michael@0 | 183 | }(); |
michael@0 | 184 | |
michael@0 | 185 | iter.next(); |
michael@0 | 186 | }, |
michael@0 | 187 | |
michael@0 | 188 | function () { |
michael@0 | 189 | // Add downloads (within the past hour). |
michael@0 | 190 | Task.spawn(function () { |
michael@0 | 191 | downloadIDs = []; |
michael@0 | 192 | for (let i = 0; i < 5; i++) { |
michael@0 | 193 | yield addDownloadWithMinutesAgo(downloadIDs, i); |
michael@0 | 194 | } |
michael@0 | 195 | |
michael@0 | 196 | doNextTest(); |
michael@0 | 197 | }).then(null, Components.utils.reportError); |
michael@0 | 198 | }, |
michael@0 | 199 | |
michael@0 | 200 | /** |
michael@0 | 201 | * Ensures that the combined history-downloads checkbox removes neither |
michael@0 | 202 | * history visits nor downloads when not checked. |
michael@0 | 203 | */ |
michael@0 | 204 | function () { |
michael@0 | 205 | // Add history, downloads, form entries (within the past hour). |
michael@0 | 206 | let uris = []; |
michael@0 | 207 | let places = []; |
michael@0 | 208 | let pURI; |
michael@0 | 209 | for (let i = 0; i < 5; i++) { |
michael@0 | 210 | pURI = makeURI("http://" + i + "-minutes-ago.com/"); |
michael@0 | 211 | places.push({uri: pURI, visitDate: visitTimeForMinutesAgo(i)}); |
michael@0 | 212 | uris.push(pURI); |
michael@0 | 213 | } |
michael@0 | 214 | |
michael@0 | 215 | addVisits(places, function() { |
michael@0 | 216 | let wh = new WindowHelper(); |
michael@0 | 217 | wh.onload = function () { |
michael@0 | 218 | is(this.isWarningPanelVisible(), false, |
michael@0 | 219 | "Warning panel should be hidden after previously accepting dialog " + |
michael@0 | 220 | "with a predefined timespan"); |
michael@0 | 221 | this.selectDuration(Sanitizer.TIMESPAN_HOUR); |
michael@0 | 222 | |
michael@0 | 223 | // Remove only form entries, leave history (including downloads). |
michael@0 | 224 | this.checkPrefCheckbox("history", false); |
michael@0 | 225 | this.checkPrefCheckbox("formdata", true); |
michael@0 | 226 | this.acceptDialog(); |
michael@0 | 227 | }; |
michael@0 | 228 | wh.onunload = function () { |
michael@0 | 229 | intPrefIs("sanitize.timeSpan", Sanitizer.TIMESPAN_HOUR, |
michael@0 | 230 | "timeSpan pref should be hour after accepting dialog with " + |
michael@0 | 231 | "hour selected"); |
michael@0 | 232 | boolPrefIs("cpd.history", false, |
michael@0 | 233 | "history pref should be false after accepting dialog with " + |
michael@0 | 234 | "history checkbox unchecked"); |
michael@0 | 235 | boolPrefIs("cpd.downloads", false, |
michael@0 | 236 | "downloads pref should be false after accepting dialog with " + |
michael@0 | 237 | "history checkbox unchecked"); |
michael@0 | 238 | |
michael@0 | 239 | // Of the three only form entries should be cleared. |
michael@0 | 240 | yield promiseHistoryClearedState(uris, false); |
michael@0 | 241 | yield ensureDownloadsClearedState(downloadIDs, false); |
michael@0 | 242 | |
michael@0 | 243 | formEntries.forEach(function (entry) { |
michael@0 | 244 | let exists = yield formNameExists(entry); |
michael@0 | 245 | is(exists, false, "form entry " + entry + " should no longer exist"); |
michael@0 | 246 | }); |
michael@0 | 247 | |
michael@0 | 248 | // OK, done, cleanup after ourselves. |
michael@0 | 249 | yield blankSlate(); |
michael@0 | 250 | yield promiseHistoryClearedState(uris, true); |
michael@0 | 251 | yield ensureDownloadsClearedState(downloadIDs, true); |
michael@0 | 252 | }; |
michael@0 | 253 | wh.open(); |
michael@0 | 254 | }); |
michael@0 | 255 | }, |
michael@0 | 256 | |
michael@0 | 257 | /** |
michael@0 | 258 | * Ensures that the "Everything" duration option works. |
michael@0 | 259 | */ |
michael@0 | 260 | function () { |
michael@0 | 261 | // Add history. |
michael@0 | 262 | let uris = []; |
michael@0 | 263 | let places = []; |
michael@0 | 264 | let pURI; |
michael@0 | 265 | // within past hour, within past two hours, within past four hours and |
michael@0 | 266 | // outside past four hours |
michael@0 | 267 | [10, 70, 130, 250].forEach(function(aValue) { |
michael@0 | 268 | pURI = makeURI("http://" + aValue + "-minutes-ago.com/"); |
michael@0 | 269 | places.push({uri: pURI, visitDate: visitTimeForMinutesAgo(aValue)}); |
michael@0 | 270 | uris.push(pURI); |
michael@0 | 271 | }); |
michael@0 | 272 | addVisits(places, function() { |
michael@0 | 273 | let wh = new WindowHelper(); |
michael@0 | 274 | wh.onload = function () { |
michael@0 | 275 | is(this.isWarningPanelVisible(), false, |
michael@0 | 276 | "Warning panel should be hidden after previously accepting dialog " + |
michael@0 | 277 | "with a predefined timespan"); |
michael@0 | 278 | this.selectDuration(Sanitizer.TIMESPAN_EVERYTHING); |
michael@0 | 279 | this.checkPrefCheckbox("history", true); |
michael@0 | 280 | this.checkDetails(true); |
michael@0 | 281 | |
michael@0 | 282 | // Hide details |
michael@0 | 283 | this.toggleDetails(); |
michael@0 | 284 | this.checkDetails(false); |
michael@0 | 285 | |
michael@0 | 286 | // Show details |
michael@0 | 287 | this.toggleDetails(); |
michael@0 | 288 | this.checkDetails(true); |
michael@0 | 289 | |
michael@0 | 290 | this.acceptDialog(); |
michael@0 | 291 | }; |
michael@0 | 292 | wh.onunload = function () { |
michael@0 | 293 | intPrefIs("sanitize.timeSpan", Sanitizer.TIMESPAN_EVERYTHING, |
michael@0 | 294 | "timeSpan pref should be everything after accepting dialog " + |
michael@0 | 295 | "with everything selected"); |
michael@0 | 296 | |
michael@0 | 297 | yield promiseHistoryClearedState(uris, true); |
michael@0 | 298 | }; |
michael@0 | 299 | wh.open(); |
michael@0 | 300 | }); |
michael@0 | 301 | }, |
michael@0 | 302 | |
michael@0 | 303 | /** |
michael@0 | 304 | * Ensures that the "Everything" warning is visible on dialog open after |
michael@0 | 305 | * the previous test. |
michael@0 | 306 | */ |
michael@0 | 307 | function () { |
michael@0 | 308 | // Add history. |
michael@0 | 309 | let uris = []; |
michael@0 | 310 | let places = []; |
michael@0 | 311 | let pURI; |
michael@0 | 312 | // within past hour, within past two hours, within past four hours and |
michael@0 | 313 | // outside past four hours |
michael@0 | 314 | [10, 70, 130, 250].forEach(function(aValue) { |
michael@0 | 315 | pURI = makeURI("http://" + aValue + "-minutes-ago.com/"); |
michael@0 | 316 | places.push({uri: pURI, visitDate: visitTimeForMinutesAgo(aValue)}); |
michael@0 | 317 | uris.push(pURI); |
michael@0 | 318 | }); |
michael@0 | 319 | addVisits(places, function() { |
michael@0 | 320 | let wh = new WindowHelper(); |
michael@0 | 321 | wh.onload = function () { |
michael@0 | 322 | is(this.isWarningPanelVisible(), true, |
michael@0 | 323 | "Warning panel should be visible after previously accepting dialog " + |
michael@0 | 324 | "with clearing everything"); |
michael@0 | 325 | this.selectDuration(Sanitizer.TIMESPAN_EVERYTHING); |
michael@0 | 326 | this.checkPrefCheckbox("history", true); |
michael@0 | 327 | this.acceptDialog(); |
michael@0 | 328 | }; |
michael@0 | 329 | wh.onunload = function () { |
michael@0 | 330 | intPrefIs("sanitize.timeSpan", Sanitizer.TIMESPAN_EVERYTHING, |
michael@0 | 331 | "timeSpan pref should be everything after accepting dialog " + |
michael@0 | 332 | "with everything selected"); |
michael@0 | 333 | |
michael@0 | 334 | yield promiseHistoryClearedState(uris, true); |
michael@0 | 335 | }; |
michael@0 | 336 | wh.open(); |
michael@0 | 337 | }); |
michael@0 | 338 | }, |
michael@0 | 339 | |
michael@0 | 340 | /** |
michael@0 | 341 | * Add form history entry for the next test. |
michael@0 | 342 | */ |
michael@0 | 343 | function () { |
michael@0 | 344 | let iter = function() { |
michael@0 | 345 | formEntries = [ addFormEntryWithMinutesAgo(iter, 10) ]; |
michael@0 | 346 | yield undefined; |
michael@0 | 347 | doNextTest(); |
michael@0 | 348 | }(); |
michael@0 | 349 | |
michael@0 | 350 | iter.next(); |
michael@0 | 351 | }, |
michael@0 | 352 | |
michael@0 | 353 | /** |
michael@0 | 354 | * The next three tests checks that when a certain history item cannot be |
michael@0 | 355 | * cleared then the checkbox should be both disabled and unchecked. |
michael@0 | 356 | * In addition, we ensure that this behavior does not modify the preferences. |
michael@0 | 357 | */ |
michael@0 | 358 | function () { |
michael@0 | 359 | // Add history. |
michael@0 | 360 | let pURI = makeURI("http://" + 10 + "-minutes-ago.com/"); |
michael@0 | 361 | addVisits({uri: pURI, visitDate: visitTimeForMinutesAgo(10)}, function() { |
michael@0 | 362 | let uris = [ pURI ]; |
michael@0 | 363 | |
michael@0 | 364 | let wh = new WindowHelper(); |
michael@0 | 365 | wh.onload = function() { |
michael@0 | 366 | // Check that the relevant checkboxes are enabled |
michael@0 | 367 | var cb = this.win.document.querySelectorAll( |
michael@0 | 368 | "#itemList > [preference='privacy.cpd.formdata']"); |
michael@0 | 369 | ok(cb.length == 1 && !cb[0].disabled, "There is formdata, checkbox to " + |
michael@0 | 370 | "clear formdata should be enabled."); |
michael@0 | 371 | |
michael@0 | 372 | var cb = this.win.document.querySelectorAll( |
michael@0 | 373 | "#itemList > [preference='privacy.cpd.history']"); |
michael@0 | 374 | ok(cb.length == 1 && !cb[0].disabled, "There is history, checkbox to " + |
michael@0 | 375 | "clear history should be enabled."); |
michael@0 | 376 | |
michael@0 | 377 | this.checkAllCheckboxes(); |
michael@0 | 378 | this.acceptDialog(); |
michael@0 | 379 | }; |
michael@0 | 380 | wh.onunload = function () { |
michael@0 | 381 | yield promiseHistoryClearedState(uris, true); |
michael@0 | 382 | |
michael@0 | 383 | let exists = yield formNameExists(formEntries[0]); |
michael@0 | 384 | is(exists, false, "form entry " + formEntries[0] + " should no longer exist"); |
michael@0 | 385 | }; |
michael@0 | 386 | wh.open(); |
michael@0 | 387 | }); |
michael@0 | 388 | }, |
michael@0 | 389 | function () { |
michael@0 | 390 | let wh = new WindowHelper(); |
michael@0 | 391 | wh.onload = function() { |
michael@0 | 392 | boolPrefIs("cpd.history", true, |
michael@0 | 393 | "history pref should be true after accepting dialog with " + |
michael@0 | 394 | "history checkbox checked"); |
michael@0 | 395 | boolPrefIs("cpd.formdata", true, |
michael@0 | 396 | "formdata pref should be true after accepting dialog with " + |
michael@0 | 397 | "formdata checkbox checked"); |
michael@0 | 398 | |
michael@0 | 399 | |
michael@0 | 400 | // Even though the formdata pref is true, because there is no history |
michael@0 | 401 | // left to clear, the checkbox will be disabled. |
michael@0 | 402 | var cb = this.win.document.querySelectorAll( |
michael@0 | 403 | "#itemList > [preference='privacy.cpd.formdata']"); |
michael@0 | 404 | ok(cb.length == 1 && cb[0].disabled && !cb[0].checked, |
michael@0 | 405 | "There is no formdata history, checkbox should be disabled and be " + |
michael@0 | 406 | "cleared to reduce user confusion (bug 497664)."); |
michael@0 | 407 | |
michael@0 | 408 | var cb = this.win.document.querySelectorAll( |
michael@0 | 409 | "#itemList > [preference='privacy.cpd.history']"); |
michael@0 | 410 | ok(cb.length == 1 && !cb[0].disabled && cb[0].checked, |
michael@0 | 411 | "There is no history, but history checkbox should always be enabled " + |
michael@0 | 412 | "and will be checked from previous preference."); |
michael@0 | 413 | |
michael@0 | 414 | this.acceptDialog(); |
michael@0 | 415 | } |
michael@0 | 416 | wh.open(); |
michael@0 | 417 | }, |
michael@0 | 418 | |
michael@0 | 419 | /** |
michael@0 | 420 | * Add form history entry for the next test. |
michael@0 | 421 | */ |
michael@0 | 422 | function () { |
michael@0 | 423 | let iter = function() { |
michael@0 | 424 | formEntries = [ addFormEntryWithMinutesAgo(iter, 10) ]; |
michael@0 | 425 | yield undefined; |
michael@0 | 426 | doNextTest(); |
michael@0 | 427 | }(); |
michael@0 | 428 | |
michael@0 | 429 | iter.next(); |
michael@0 | 430 | }, |
michael@0 | 431 | |
michael@0 | 432 | function () { |
michael@0 | 433 | let wh = new WindowHelper(); |
michael@0 | 434 | wh.onload = function() { |
michael@0 | 435 | boolPrefIs("cpd.formdata", true, |
michael@0 | 436 | "formdata pref should persist previous value after accepting " + |
michael@0 | 437 | "dialog where you could not clear formdata."); |
michael@0 | 438 | |
michael@0 | 439 | var cb = this.win.document.querySelectorAll( |
michael@0 | 440 | "#itemList > [preference='privacy.cpd.formdata']"); |
michael@0 | 441 | ok(cb.length == 1 && !cb[0].disabled && cb[0].checked, |
michael@0 | 442 | "There exists formEntries so the checkbox should be in sync with " + |
michael@0 | 443 | "the pref."); |
michael@0 | 444 | |
michael@0 | 445 | this.acceptDialog(); |
michael@0 | 446 | }; |
michael@0 | 447 | wh.onunload = function () { |
michael@0 | 448 | let exists = yield formNameExists(formEntries[0]); |
michael@0 | 449 | is(exists, false, "form entry " + formEntries[0] + " should no longer exist"); |
michael@0 | 450 | }; |
michael@0 | 451 | wh.open(); |
michael@0 | 452 | }, |
michael@0 | 453 | |
michael@0 | 454 | |
michael@0 | 455 | /** |
michael@0 | 456 | * These next six tests together ensure that toggling details persists |
michael@0 | 457 | * across dialog openings. |
michael@0 | 458 | */ |
michael@0 | 459 | function () { |
michael@0 | 460 | let wh = new WindowHelper(); |
michael@0 | 461 | wh.onload = function () { |
michael@0 | 462 | // Check all items and select "Everything" |
michael@0 | 463 | this.checkAllCheckboxes(); |
michael@0 | 464 | this.selectDuration(Sanitizer.TIMESPAN_EVERYTHING); |
michael@0 | 465 | |
michael@0 | 466 | // Hide details |
michael@0 | 467 | this.toggleDetails(); |
michael@0 | 468 | this.checkDetails(false); |
michael@0 | 469 | this.acceptDialog(); |
michael@0 | 470 | }; |
michael@0 | 471 | wh.open(); |
michael@0 | 472 | }, |
michael@0 | 473 | function () { |
michael@0 | 474 | let wh = new WindowHelper(); |
michael@0 | 475 | wh.onload = function () { |
michael@0 | 476 | // Details should remain closed because all items are checked. |
michael@0 | 477 | this.checkDetails(false); |
michael@0 | 478 | |
michael@0 | 479 | // Uncheck history. |
michael@0 | 480 | this.checkPrefCheckbox("history", false); |
michael@0 | 481 | this.acceptDialog(); |
michael@0 | 482 | }; |
michael@0 | 483 | wh.open(); |
michael@0 | 484 | }, |
michael@0 | 485 | function () { |
michael@0 | 486 | let wh = new WindowHelper(); |
michael@0 | 487 | wh.onload = function () { |
michael@0 | 488 | // Details should be open because not all items are checked. |
michael@0 | 489 | this.checkDetails(true); |
michael@0 | 490 | |
michael@0 | 491 | // Modify the Site Preferences item state (bug 527820) |
michael@0 | 492 | this.checkAllCheckboxes(); |
michael@0 | 493 | this.checkPrefCheckbox("siteSettings", false); |
michael@0 | 494 | this.acceptDialog(); |
michael@0 | 495 | }; |
michael@0 | 496 | wh.open(); |
michael@0 | 497 | }, |
michael@0 | 498 | function () { |
michael@0 | 499 | let wh = new WindowHelper(); |
michael@0 | 500 | wh.onload = function () { |
michael@0 | 501 | // Details should be open because not all items are checked. |
michael@0 | 502 | this.checkDetails(true); |
michael@0 | 503 | |
michael@0 | 504 | // Hide details |
michael@0 | 505 | this.toggleDetails(); |
michael@0 | 506 | this.checkDetails(false); |
michael@0 | 507 | this.cancelDialog(); |
michael@0 | 508 | }; |
michael@0 | 509 | wh.open(); |
michael@0 | 510 | }, |
michael@0 | 511 | function () { |
michael@0 | 512 | let wh = new WindowHelper(); |
michael@0 | 513 | wh.onload = function () { |
michael@0 | 514 | // Details should be open because not all items are checked. |
michael@0 | 515 | this.checkDetails(true); |
michael@0 | 516 | |
michael@0 | 517 | // Select another duration |
michael@0 | 518 | this.selectDuration(Sanitizer.TIMESPAN_HOUR); |
michael@0 | 519 | // Hide details |
michael@0 | 520 | this.toggleDetails(); |
michael@0 | 521 | this.checkDetails(false); |
michael@0 | 522 | this.acceptDialog(); |
michael@0 | 523 | }; |
michael@0 | 524 | wh.open(); |
michael@0 | 525 | }, |
michael@0 | 526 | function () { |
michael@0 | 527 | let wh = new WindowHelper(); |
michael@0 | 528 | wh.onload = function () { |
michael@0 | 529 | // Details should not be open because "Last Hour" is selected |
michael@0 | 530 | this.checkDetails(false); |
michael@0 | 531 | |
michael@0 | 532 | this.cancelDialog(); |
michael@0 | 533 | }; |
michael@0 | 534 | wh.open(); |
michael@0 | 535 | }, |
michael@0 | 536 | function () { |
michael@0 | 537 | let wh = new WindowHelper(); |
michael@0 | 538 | wh.onload = function () { |
michael@0 | 539 | // Details should have remained closed |
michael@0 | 540 | this.checkDetails(false); |
michael@0 | 541 | |
michael@0 | 542 | // Show details |
michael@0 | 543 | this.toggleDetails(); |
michael@0 | 544 | this.checkDetails(true); |
michael@0 | 545 | this.cancelDialog(); |
michael@0 | 546 | }; |
michael@0 | 547 | wh.open(); |
michael@0 | 548 | }, |
michael@0 | 549 | function () { |
michael@0 | 550 | // Test for offline cache deletion |
michael@0 | 551 | |
michael@0 | 552 | // Prepare stuff, we will work with www.example.com |
michael@0 | 553 | var URL = "http://www.example.com"; |
michael@0 | 554 | |
michael@0 | 555 | var ios = Cc["@mozilla.org/network/io-service;1"] |
michael@0 | 556 | .getService(Ci.nsIIOService); |
michael@0 | 557 | var URI = ios.newURI(URL, null, null); |
michael@0 | 558 | |
michael@0 | 559 | var sm = Cc["@mozilla.org/scriptsecuritymanager;1"] |
michael@0 | 560 | .getService(Ci.nsIScriptSecurityManager); |
michael@0 | 561 | var principal = sm.getNoAppCodebasePrincipal(URI); |
michael@0 | 562 | |
michael@0 | 563 | // Give www.example.com privileges to store offline data |
michael@0 | 564 | var pm = Cc["@mozilla.org/permissionmanager;1"] |
michael@0 | 565 | .getService(Ci.nsIPermissionManager); |
michael@0 | 566 | pm.addFromPrincipal(principal, "offline-app", Ci.nsIPermissionManager.ALLOW_ACTION); |
michael@0 | 567 | pm.addFromPrincipal(principal, "offline-app", Ci.nsIOfflineCacheUpdateService.ALLOW_NO_WARN); |
michael@0 | 568 | |
michael@0 | 569 | // Store something to the offline cache |
michael@0 | 570 | const nsICache = Components.interfaces.nsICache; |
michael@0 | 571 | var cs = Components.classes["@mozilla.org/network/cache-service;1"] |
michael@0 | 572 | .getService(Components.interfaces.nsICacheService); |
michael@0 | 573 | var session = cs.createSession(URL + "/manifest", nsICache.STORE_OFFLINE, nsICache.STREAM_BASED); |
michael@0 | 574 | |
michael@0 | 575 | // Open the dialog |
michael@0 | 576 | let wh = new WindowHelper(); |
michael@0 | 577 | wh.onload = function () { |
michael@0 | 578 | this.selectDuration(Sanitizer.TIMESPAN_EVERYTHING); |
michael@0 | 579 | // Show details |
michael@0 | 580 | this.toggleDetails(); |
michael@0 | 581 | // Clear only offlineApps |
michael@0 | 582 | this.uncheckAllCheckboxes(); |
michael@0 | 583 | this.checkPrefCheckbox("offlineApps", true); |
michael@0 | 584 | this.acceptDialog(); |
michael@0 | 585 | }; |
michael@0 | 586 | wh.onunload = function () { |
michael@0 | 587 | // Check if the cache has been deleted |
michael@0 | 588 | var size = -1; |
michael@0 | 589 | var visitor = { |
michael@0 | 590 | visitDevice: function (deviceID, deviceInfo) |
michael@0 | 591 | { |
michael@0 | 592 | if (deviceID == "offline") |
michael@0 | 593 | size = deviceInfo.totalSize; |
michael@0 | 594 | |
michael@0 | 595 | // Do not enumerate entries |
michael@0 | 596 | return false; |
michael@0 | 597 | }, |
michael@0 | 598 | |
michael@0 | 599 | visitEntry: function (deviceID, entryInfo) |
michael@0 | 600 | { |
michael@0 | 601 | // Do not enumerate entries. |
michael@0 | 602 | return false; |
michael@0 | 603 | } |
michael@0 | 604 | }; |
michael@0 | 605 | cs.visitEntries(visitor); |
michael@0 | 606 | is(size, 0, "offline application cache entries evicted"); |
michael@0 | 607 | }; |
michael@0 | 608 | |
michael@0 | 609 | var cacheListener = { |
michael@0 | 610 | onCacheEntryAvailable: function (entry, access, status) { |
michael@0 | 611 | is(status, Cr.NS_OK); |
michael@0 | 612 | var stream = entry.openOutputStream(0); |
michael@0 | 613 | var content = "content"; |
michael@0 | 614 | stream.write(content, content.length); |
michael@0 | 615 | stream.close(); |
michael@0 | 616 | entry.close(); |
michael@0 | 617 | wh.open(); |
michael@0 | 618 | } |
michael@0 | 619 | }; |
michael@0 | 620 | |
michael@0 | 621 | session.asyncOpenCacheEntry(URL, nsICache.ACCESS_READ_WRITE, cacheListener); |
michael@0 | 622 | }, |
michael@0 | 623 | function () { |
michael@0 | 624 | // Test for offline apps permission deletion |
michael@0 | 625 | |
michael@0 | 626 | // Prepare stuff, we will work with www.example.com |
michael@0 | 627 | var URL = "http://www.example.com"; |
michael@0 | 628 | |
michael@0 | 629 | var ios = Cc["@mozilla.org/network/io-service;1"] |
michael@0 | 630 | .getService(Ci.nsIIOService); |
michael@0 | 631 | var URI = ios.newURI(URL, null, null); |
michael@0 | 632 | |
michael@0 | 633 | var sm = Cc["@mozilla.org/scriptsecuritymanager;1"] |
michael@0 | 634 | .getService(Ci.nsIScriptSecurityManager); |
michael@0 | 635 | var principal = sm.getNoAppCodebasePrincipal(URI); |
michael@0 | 636 | |
michael@0 | 637 | // Open the dialog |
michael@0 | 638 | let wh = new WindowHelper(); |
michael@0 | 639 | wh.onload = function () { |
michael@0 | 640 | this.selectDuration(Sanitizer.TIMESPAN_EVERYTHING); |
michael@0 | 641 | // Show details |
michael@0 | 642 | this.toggleDetails(); |
michael@0 | 643 | // Clear only offlineApps |
michael@0 | 644 | this.uncheckAllCheckboxes(); |
michael@0 | 645 | this.checkPrefCheckbox("siteSettings", true); |
michael@0 | 646 | this.acceptDialog(); |
michael@0 | 647 | }; |
michael@0 | 648 | wh.onunload = function () { |
michael@0 | 649 | // Check all has been deleted (privileges, data, cache) |
michael@0 | 650 | var pm = Cc["@mozilla.org/permissionmanager;1"] |
michael@0 | 651 | .getService(Ci.nsIPermissionManager); |
michael@0 | 652 | is(pm.testPermissionFromPrincipal(principal, "offline-app"), 0, "offline-app permissions removed"); |
michael@0 | 653 | }; |
michael@0 | 654 | wh.open(); |
michael@0 | 655 | } |
michael@0 | 656 | ]; |
michael@0 | 657 | |
michael@0 | 658 | // Index in gAllTests of the test currently being run. Incremented for each |
michael@0 | 659 | // test run. See doNextTest(). |
michael@0 | 660 | var gCurrTest = 0; |
michael@0 | 661 | |
michael@0 | 662 | let now_mSec = Date.now(); |
michael@0 | 663 | let now_uSec = now_mSec * 1000; |
michael@0 | 664 | |
michael@0 | 665 | /////////////////////////////////////////////////////////////////////////////// |
michael@0 | 666 | |
michael@0 | 667 | /** |
michael@0 | 668 | * This wraps the dialog and provides some convenience methods for interacting |
michael@0 | 669 | * with it. |
michael@0 | 670 | * |
michael@0 | 671 | * @param aWin |
michael@0 | 672 | * The dialog's nsIDOMWindow |
michael@0 | 673 | */ |
michael@0 | 674 | function WindowHelper(aWin) { |
michael@0 | 675 | this.win = aWin; |
michael@0 | 676 | } |
michael@0 | 677 | |
michael@0 | 678 | WindowHelper.prototype = { |
michael@0 | 679 | /** |
michael@0 | 680 | * "Presses" the dialog's OK button. |
michael@0 | 681 | */ |
michael@0 | 682 | acceptDialog: function () { |
michael@0 | 683 | is(this.win.document.documentElement.getButton("accept").disabled, false, |
michael@0 | 684 | "Dialog's OK button should not be disabled"); |
michael@0 | 685 | this.win.document.documentElement.acceptDialog(); |
michael@0 | 686 | }, |
michael@0 | 687 | |
michael@0 | 688 | /** |
michael@0 | 689 | * "Presses" the dialog's Cancel button. |
michael@0 | 690 | */ |
michael@0 | 691 | cancelDialog: function () { |
michael@0 | 692 | this.win.document.documentElement.cancelDialog(); |
michael@0 | 693 | }, |
michael@0 | 694 | |
michael@0 | 695 | /** |
michael@0 | 696 | * Ensures that the details progressive disclosure button and the item list |
michael@0 | 697 | * hidden by it match up. Also makes sure the height of the dialog is |
michael@0 | 698 | * sufficient for the item list and warning panel. |
michael@0 | 699 | * |
michael@0 | 700 | * @param aShouldBeShown |
michael@0 | 701 | * True if you expect the details to be shown and false if hidden |
michael@0 | 702 | */ |
michael@0 | 703 | checkDetails: function (aShouldBeShown) { |
michael@0 | 704 | let button = this.getDetailsButton(); |
michael@0 | 705 | let list = this.getItemList(); |
michael@0 | 706 | let hidden = list.hidden || list.collapsed; |
michael@0 | 707 | is(hidden, !aShouldBeShown, |
michael@0 | 708 | "Details should be " + (aShouldBeShown ? "shown" : "hidden") + |
michael@0 | 709 | " but were actually " + (hidden ? "hidden" : "shown")); |
michael@0 | 710 | let dir = hidden ? "down" : "up"; |
michael@0 | 711 | is(button.className, "expander-" + dir, |
michael@0 | 712 | "Details button should be " + dir + " because item list is " + |
michael@0 | 713 | (hidden ? "" : "not ") + "hidden"); |
michael@0 | 714 | let height = 0; |
michael@0 | 715 | if (!hidden) { |
michael@0 | 716 | ok(list.boxObject.height > 30, "listbox has sufficient size") |
michael@0 | 717 | height += list.boxObject.height; |
michael@0 | 718 | } |
michael@0 | 719 | if (this.isWarningPanelVisible()) |
michael@0 | 720 | height += this.getWarningPanel().boxObject.height; |
michael@0 | 721 | ok(height < this.win.innerHeight, |
michael@0 | 722 | "Window should be tall enough to fit warning panel and item list"); |
michael@0 | 723 | }, |
michael@0 | 724 | |
michael@0 | 725 | /** |
michael@0 | 726 | * (Un)checks a history scope checkbox (browser & download history, |
michael@0 | 727 | * form history, etc.). |
michael@0 | 728 | * |
michael@0 | 729 | * @param aPrefName |
michael@0 | 730 | * The final portion of the checkbox's privacy.cpd.* preference name |
michael@0 | 731 | * @param aCheckState |
michael@0 | 732 | * True if the checkbox should be checked, false otherwise |
michael@0 | 733 | */ |
michael@0 | 734 | checkPrefCheckbox: function (aPrefName, aCheckState) { |
michael@0 | 735 | var pref = "privacy.cpd." + aPrefName; |
michael@0 | 736 | var cb = this.win.document.querySelectorAll( |
michael@0 | 737 | "#itemList > [preference='" + pref + "']"); |
michael@0 | 738 | is(cb.length, 1, "found checkbox for " + pref + " preference"); |
michael@0 | 739 | if (cb[0].checked != aCheckState) |
michael@0 | 740 | cb[0].click(); |
michael@0 | 741 | }, |
michael@0 | 742 | |
michael@0 | 743 | /** |
michael@0 | 744 | * Makes sure all the checkboxes are checked. |
michael@0 | 745 | */ |
michael@0 | 746 | _checkAllCheckboxesCustom: function (check) { |
michael@0 | 747 | var cb = this.win.document.querySelectorAll("#itemList > [preference]"); |
michael@0 | 748 | ok(cb.length > 1, "found checkboxes for preferences"); |
michael@0 | 749 | for (var i = 0; i < cb.length; ++i) { |
michael@0 | 750 | var pref = this.win.document.getElementById(cb[i].getAttribute("preference")); |
michael@0 | 751 | if (!!pref.value ^ check) |
michael@0 | 752 | cb[i].click(); |
michael@0 | 753 | } |
michael@0 | 754 | }, |
michael@0 | 755 | |
michael@0 | 756 | checkAllCheckboxes: function () { |
michael@0 | 757 | this._checkAllCheckboxesCustom(true); |
michael@0 | 758 | }, |
michael@0 | 759 | |
michael@0 | 760 | uncheckAllCheckboxes: function () { |
michael@0 | 761 | this._checkAllCheckboxesCustom(false); |
michael@0 | 762 | }, |
michael@0 | 763 | |
michael@0 | 764 | /** |
michael@0 | 765 | * @return The details progressive disclosure button |
michael@0 | 766 | */ |
michael@0 | 767 | getDetailsButton: function () { |
michael@0 | 768 | return this.win.document.getElementById("detailsExpander"); |
michael@0 | 769 | }, |
michael@0 | 770 | |
michael@0 | 771 | /** |
michael@0 | 772 | * @return The dialog's duration dropdown |
michael@0 | 773 | */ |
michael@0 | 774 | getDurationDropdown: function () { |
michael@0 | 775 | return this.win.document.getElementById("sanitizeDurationChoice"); |
michael@0 | 776 | }, |
michael@0 | 777 | |
michael@0 | 778 | /** |
michael@0 | 779 | * @return The item list hidden by the details progressive disclosure button |
michael@0 | 780 | */ |
michael@0 | 781 | getItemList: function () { |
michael@0 | 782 | return this.win.document.getElementById("itemList"); |
michael@0 | 783 | }, |
michael@0 | 784 | |
michael@0 | 785 | /** |
michael@0 | 786 | * @return The clear-everything warning box |
michael@0 | 787 | */ |
michael@0 | 788 | getWarningPanel: function () { |
michael@0 | 789 | return this.win.document.getElementById("sanitizeEverythingWarningBox"); |
michael@0 | 790 | }, |
michael@0 | 791 | |
michael@0 | 792 | /** |
michael@0 | 793 | * @return True if the "Everything" warning panel is visible (as opposed to |
michael@0 | 794 | * the tree) |
michael@0 | 795 | */ |
michael@0 | 796 | isWarningPanelVisible: function () { |
michael@0 | 797 | return !this.getWarningPanel().hidden; |
michael@0 | 798 | }, |
michael@0 | 799 | |
michael@0 | 800 | /** |
michael@0 | 801 | * Opens the clear recent history dialog. Before calling this, set |
michael@0 | 802 | * this.onload to a function to execute onload. It should close the dialog |
michael@0 | 803 | * when done so that the tests may continue. Set this.onunload to a function |
michael@0 | 804 | * to execute onunload. this.onunload is optional. If it returns true, the |
michael@0 | 805 | * caller is expected to call waitForAsyncUpdates at some point; if false is |
michael@0 | 806 | * returned, waitForAsyncUpdates is called automatically. |
michael@0 | 807 | */ |
michael@0 | 808 | open: function () { |
michael@0 | 809 | let wh = this; |
michael@0 | 810 | |
michael@0 | 811 | function windowObserver(aSubject, aTopic, aData) { |
michael@0 | 812 | if (aTopic != "domwindowopened") |
michael@0 | 813 | return; |
michael@0 | 814 | |
michael@0 | 815 | Services.ww.unregisterNotification(windowObserver); |
michael@0 | 816 | |
michael@0 | 817 | var loaded = false; |
michael@0 | 818 | let win = aSubject.QueryInterface(Ci.nsIDOMWindow); |
michael@0 | 819 | |
michael@0 | 820 | win.addEventListener("load", function onload(event) { |
michael@0 | 821 | win.removeEventListener("load", onload, false); |
michael@0 | 822 | |
michael@0 | 823 | if (win.name !== "SanitizeDialog") |
michael@0 | 824 | return; |
michael@0 | 825 | |
michael@0 | 826 | wh.win = win; |
michael@0 | 827 | loaded = true; |
michael@0 | 828 | |
michael@0 | 829 | executeSoon(function () { |
michael@0 | 830 | // Some exceptions that reach here don't reach the test harness, but |
michael@0 | 831 | // ok()/is() do... |
michael@0 | 832 | try { |
michael@0 | 833 | wh.onload(); |
michael@0 | 834 | } |
michael@0 | 835 | catch (exc) { |
michael@0 | 836 | win.close(); |
michael@0 | 837 | ok(false, "Unexpected exception: " + exc + "\n" + exc.stack); |
michael@0 | 838 | finish(); |
michael@0 | 839 | } |
michael@0 | 840 | }); |
michael@0 | 841 | }, false); |
michael@0 | 842 | |
michael@0 | 843 | win.addEventListener("unload", function onunload(event) { |
michael@0 | 844 | if (win.name !== "SanitizeDialog") { |
michael@0 | 845 | win.removeEventListener("unload", onunload, false); |
michael@0 | 846 | return; |
michael@0 | 847 | } |
michael@0 | 848 | |
michael@0 | 849 | // Why is unload fired before load? |
michael@0 | 850 | if (!loaded) |
michael@0 | 851 | return; |
michael@0 | 852 | |
michael@0 | 853 | win.removeEventListener("unload", onunload, false); |
michael@0 | 854 | wh.win = win; |
michael@0 | 855 | |
michael@0 | 856 | executeSoon(function () { |
michael@0 | 857 | // Some exceptions that reach here don't reach the test harness, but |
michael@0 | 858 | // ok()/is() do... |
michael@0 | 859 | try { |
michael@0 | 860 | if (wh.onunload) { |
michael@0 | 861 | Task.spawn(wh.onunload).then(function() { |
michael@0 | 862 | waitForAsyncUpdates(doNextTest); |
michael@0 | 863 | }).then(null, Components.utils.reportError); |
michael@0 | 864 | } else { |
michael@0 | 865 | waitForAsyncUpdates(doNextTest); |
michael@0 | 866 | } |
michael@0 | 867 | } |
michael@0 | 868 | catch (exc) { |
michael@0 | 869 | win.close(); |
michael@0 | 870 | ok(false, "Unexpected exception: " + exc + "\n" + exc.stack); |
michael@0 | 871 | finish(); |
michael@0 | 872 | } |
michael@0 | 873 | }); |
michael@0 | 874 | }, false); |
michael@0 | 875 | } |
michael@0 | 876 | Services.ww.registerNotification(windowObserver); |
michael@0 | 877 | Services.ww.openWindow(null, |
michael@0 | 878 | "chrome://browser/content/sanitize.xul", |
michael@0 | 879 | "SanitizeDialog", |
michael@0 | 880 | "chrome,titlebar,dialog,centerscreen,modal", |
michael@0 | 881 | null); |
michael@0 | 882 | }, |
michael@0 | 883 | |
michael@0 | 884 | /** |
michael@0 | 885 | * Selects a duration in the duration dropdown. |
michael@0 | 886 | * |
michael@0 | 887 | * @param aDurVal |
michael@0 | 888 | * One of the Sanitizer.TIMESPAN_* values |
michael@0 | 889 | */ |
michael@0 | 890 | selectDuration: function (aDurVal) { |
michael@0 | 891 | this.getDurationDropdown().value = aDurVal; |
michael@0 | 892 | if (aDurVal === Sanitizer.TIMESPAN_EVERYTHING) { |
michael@0 | 893 | is(this.isWarningPanelVisible(), true, |
michael@0 | 894 | "Warning panel should be visible for TIMESPAN_EVERYTHING"); |
michael@0 | 895 | } |
michael@0 | 896 | else { |
michael@0 | 897 | is(this.isWarningPanelVisible(), false, |
michael@0 | 898 | "Warning panel should not be visible for non-TIMESPAN_EVERYTHING"); |
michael@0 | 899 | } |
michael@0 | 900 | }, |
michael@0 | 901 | |
michael@0 | 902 | /** |
michael@0 | 903 | * Toggles the details progressive disclosure button. |
michael@0 | 904 | */ |
michael@0 | 905 | toggleDetails: function () { |
michael@0 | 906 | this.getDetailsButton().click(); |
michael@0 | 907 | } |
michael@0 | 908 | }; |
michael@0 | 909 | |
michael@0 | 910 | /** |
michael@0 | 911 | * Adds a download to history. |
michael@0 | 912 | * |
michael@0 | 913 | * @param aMinutesAgo |
michael@0 | 914 | * The download will be downloaded this many minutes ago |
michael@0 | 915 | */ |
michael@0 | 916 | function addDownloadWithMinutesAgo(aExpectedPathList, aMinutesAgo) { |
michael@0 | 917 | let publicList = yield Downloads.getList(Downloads.PUBLIC); |
michael@0 | 918 | |
michael@0 | 919 | let name = "fakefile-" + aMinutesAgo + "-minutes-ago"; |
michael@0 | 920 | let download = yield Downloads.createDownload({ |
michael@0 | 921 | source: "https://bugzilla.mozilla.org/show_bug.cgi?id=480169", |
michael@0 | 922 | target: name |
michael@0 | 923 | }); |
michael@0 | 924 | download.startTime = new Date(now_mSec - (aMinutesAgo * kMsecPerMin)); |
michael@0 | 925 | download.canceled = true; |
michael@0 | 926 | publicList.add(download); |
michael@0 | 927 | |
michael@0 | 928 | ok((yield downloadExists(name)), |
michael@0 | 929 | "Sanity check: download " + name + |
michael@0 | 930 | " should exist after creating it"); |
michael@0 | 931 | |
michael@0 | 932 | aExpectedPathList.push(name); |
michael@0 | 933 | } |
michael@0 | 934 | |
michael@0 | 935 | /** |
michael@0 | 936 | * Adds a form entry to history. |
michael@0 | 937 | * |
michael@0 | 938 | * @param aMinutesAgo |
michael@0 | 939 | * The entry will be added this many minutes ago |
michael@0 | 940 | */ |
michael@0 | 941 | function addFormEntryWithMinutesAgo(then, aMinutesAgo) { |
michael@0 | 942 | let name = aMinutesAgo + "-minutes-ago"; |
michael@0 | 943 | |
michael@0 | 944 | // Artifically age the entry to the proper vintage. |
michael@0 | 945 | let timestamp = now_uSec - (aMinutesAgo * kUsecPerMin); |
michael@0 | 946 | |
michael@0 | 947 | FormHistory.update({ op: "add", fieldname: name, value: "dummy", firstUsed: timestamp }, |
michael@0 | 948 | { handleError: function (error) { |
michael@0 | 949 | do_throw("Error occurred updating form history: " + error); |
michael@0 | 950 | }, |
michael@0 | 951 | handleCompletion: function (reason) { then.next(); } |
michael@0 | 952 | }); |
michael@0 | 953 | return name; |
michael@0 | 954 | } |
michael@0 | 955 | |
michael@0 | 956 | /** |
michael@0 | 957 | * Checks if a form entry exists. |
michael@0 | 958 | */ |
michael@0 | 959 | function formNameExists(name) |
michael@0 | 960 | { |
michael@0 | 961 | let deferred = Promise.defer(); |
michael@0 | 962 | |
michael@0 | 963 | let count = 0; |
michael@0 | 964 | FormHistory.count({ fieldname: name }, |
michael@0 | 965 | { handleResult: function (result) count = result, |
michael@0 | 966 | handleError: function (error) { |
michael@0 | 967 | do_throw("Error occurred searching form history: " + error); |
michael@0 | 968 | deferred.reject(error); |
michael@0 | 969 | }, |
michael@0 | 970 | handleCompletion: function (reason) { |
michael@0 | 971 | if (!reason) deferred.resolve(count); |
michael@0 | 972 | } |
michael@0 | 973 | }); |
michael@0 | 974 | |
michael@0 | 975 | return deferred.promise; |
michael@0 | 976 | } |
michael@0 | 977 | |
michael@0 | 978 | /** |
michael@0 | 979 | * Removes all history visits, downloads, and form entries. |
michael@0 | 980 | */ |
michael@0 | 981 | function blankSlate() { |
michael@0 | 982 | PlacesUtils.bhistory.removeAllPages(); |
michael@0 | 983 | |
michael@0 | 984 | // The promise is resolved only when removing both downloads and form history are done. |
michael@0 | 985 | let deferred = Promise.defer(); |
michael@0 | 986 | let formHistoryDone = false, downloadsDone = false; |
michael@0 | 987 | |
michael@0 | 988 | Task.spawn(function deleteAllDownloads() { |
michael@0 | 989 | let publicList = yield Downloads.getList(Downloads.PUBLIC); |
michael@0 | 990 | let downloads = yield publicList.getAll(); |
michael@0 | 991 | for (let download of downloads) { |
michael@0 | 992 | yield publicList.remove(download); |
michael@0 | 993 | yield download.finalize(true); |
michael@0 | 994 | } |
michael@0 | 995 | downloadsDone = true; |
michael@0 | 996 | if (formHistoryDone) { |
michael@0 | 997 | deferred.resolve(); |
michael@0 | 998 | } |
michael@0 | 999 | }).then(null, Components.utils.reportError); |
michael@0 | 1000 | |
michael@0 | 1001 | FormHistory.update({ op: "remove" }, |
michael@0 | 1002 | { handleError: function (error) { |
michael@0 | 1003 | do_throw("Error occurred updating form history: " + error); |
michael@0 | 1004 | deferred.reject(error); |
michael@0 | 1005 | }, |
michael@0 | 1006 | handleCompletion: function (reason) { |
michael@0 | 1007 | if (!reason) { |
michael@0 | 1008 | formHistoryDone = true; |
michael@0 | 1009 | if (downloadsDone) { |
michael@0 | 1010 | deferred.resolve(); |
michael@0 | 1011 | } |
michael@0 | 1012 | } |
michael@0 | 1013 | } |
michael@0 | 1014 | }); |
michael@0 | 1015 | return deferred.promise; |
michael@0 | 1016 | } |
michael@0 | 1017 | |
michael@0 | 1018 | /** |
michael@0 | 1019 | * Ensures that the given pref is the expected value. |
michael@0 | 1020 | * |
michael@0 | 1021 | * @param aPrefName |
michael@0 | 1022 | * The pref's sub-branch under the privacy branch |
michael@0 | 1023 | * @param aExpectedVal |
michael@0 | 1024 | * The pref's expected value |
michael@0 | 1025 | * @param aMsg |
michael@0 | 1026 | * Passed to is() |
michael@0 | 1027 | */ |
michael@0 | 1028 | function boolPrefIs(aPrefName, aExpectedVal, aMsg) { |
michael@0 | 1029 | is(gPrefService.getBoolPref("privacy." + aPrefName), aExpectedVal, aMsg); |
michael@0 | 1030 | } |
michael@0 | 1031 | |
michael@0 | 1032 | /** |
michael@0 | 1033 | * Checks to see if the download with the specified path exists. |
michael@0 | 1034 | * |
michael@0 | 1035 | * @param aPath |
michael@0 | 1036 | * The path of the download to check |
michael@0 | 1037 | * @return True if the download exists, false otherwise |
michael@0 | 1038 | */ |
michael@0 | 1039 | function downloadExists(aPath) |
michael@0 | 1040 | { |
michael@0 | 1041 | return Task.spawn(function() { |
michael@0 | 1042 | let publicList = yield Downloads.getList(Downloads.PUBLIC); |
michael@0 | 1043 | let listArray = yield publicList.getAll(); |
michael@0 | 1044 | throw new Task.Result(listArray.some(i => i.target.path == aPath)); |
michael@0 | 1045 | }); |
michael@0 | 1046 | } |
michael@0 | 1047 | |
michael@0 | 1048 | /** |
michael@0 | 1049 | * Runs the next test in the gAllTests array. If all tests have been run, |
michael@0 | 1050 | * finishes the entire suite. |
michael@0 | 1051 | */ |
michael@0 | 1052 | function doNextTest() { |
michael@0 | 1053 | if (gAllTests.length <= gCurrTest) { |
michael@0 | 1054 | blankSlate(); |
michael@0 | 1055 | waitForAsyncUpdates(finish); |
michael@0 | 1056 | } |
michael@0 | 1057 | else { |
michael@0 | 1058 | let ct = gCurrTest; |
michael@0 | 1059 | gCurrTest++; |
michael@0 | 1060 | gAllTests[ct](); |
michael@0 | 1061 | } |
michael@0 | 1062 | } |
michael@0 | 1063 | |
michael@0 | 1064 | /** |
michael@0 | 1065 | * Ensures that the specified downloads are either cleared or not. |
michael@0 | 1066 | * |
michael@0 | 1067 | * @param aDownloadIDs |
michael@0 | 1068 | * Array of download database IDs |
michael@0 | 1069 | * @param aShouldBeCleared |
michael@0 | 1070 | * True if each download should be cleared, false otherwise |
michael@0 | 1071 | */ |
michael@0 | 1072 | function ensureDownloadsClearedState(aDownloadIDs, aShouldBeCleared) { |
michael@0 | 1073 | let niceStr = aShouldBeCleared ? "no longer" : "still"; |
michael@0 | 1074 | aDownloadIDs.forEach(function (id) { |
michael@0 | 1075 | is((yield downloadExists(id)), !aShouldBeCleared, |
michael@0 | 1076 | "download " + id + " should " + niceStr + " exist"); |
michael@0 | 1077 | }); |
michael@0 | 1078 | } |
michael@0 | 1079 | |
michael@0 | 1080 | /** |
michael@0 | 1081 | * Ensures that the given pref is the expected value. |
michael@0 | 1082 | * |
michael@0 | 1083 | * @param aPrefName |
michael@0 | 1084 | * The pref's sub-branch under the privacy branch |
michael@0 | 1085 | * @param aExpectedVal |
michael@0 | 1086 | * The pref's expected value |
michael@0 | 1087 | * @param aMsg |
michael@0 | 1088 | * Passed to is() |
michael@0 | 1089 | */ |
michael@0 | 1090 | function intPrefIs(aPrefName, aExpectedVal, aMsg) { |
michael@0 | 1091 | is(gPrefService.getIntPref("privacy." + aPrefName), aExpectedVal, aMsg); |
michael@0 | 1092 | } |
michael@0 | 1093 | |
michael@0 | 1094 | /** |
michael@0 | 1095 | * Creates a visit time. |
michael@0 | 1096 | * |
michael@0 | 1097 | * @param aMinutesAgo |
michael@0 | 1098 | * The visit will be visited this many minutes ago |
michael@0 | 1099 | */ |
michael@0 | 1100 | function visitTimeForMinutesAgo(aMinutesAgo) { |
michael@0 | 1101 | return now_uSec - aMinutesAgo * kUsecPerMin; |
michael@0 | 1102 | } |
michael@0 | 1103 | |
michael@0 | 1104 | /////////////////////////////////////////////////////////////////////////////// |
michael@0 | 1105 | |
michael@0 | 1106 | function test() { |
michael@0 | 1107 | requestLongerTimeout(2); |
michael@0 | 1108 | waitForExplicitFinish(); |
michael@0 | 1109 | blankSlate(); |
michael@0 | 1110 | // Kick off all the tests in the gAllTests array. |
michael@0 | 1111 | waitForAsyncUpdates(doNextTest); |
michael@0 | 1112 | } |