toolkit/mozapps/update/tests/chrome/utils.js

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 /* Any copyright is dedicated to the Public Domain.
michael@0 2 * http://creativecommons.org/publicdomain/zero/1.0/
michael@0 3 */
michael@0 4
michael@0 5 /**
michael@0 6 * Test Definition
michael@0 7 *
michael@0 8 * Most tests can use an array named TESTS that will perform most if not all of
michael@0 9 * the necessary checks. Each element in the array must be an object with the
michael@0 10 * following possible properties. Additional properties besides the ones listed
michael@0 11 * below can be added as needed.
michael@0 12 *
michael@0 13 * overrideCallback (optional)
michael@0 14 * The function to call for the next test. This is typically called when the
michael@0 15 * wizard page changes but can also be called for other events by the previous
michael@0 16 * test. If this property isn't defined then the defailtCallback function will
michael@0 17 * be called. If this property is defined then all other properties are
michael@0 18 * optional.
michael@0 19 *
michael@0 20 * pageid (required unless overrideCallback is specified)
michael@0 21 * The expected pageid for the wizard. This property is required unless the
michael@0 22 * overrideCallback property is defined.
michael@0 23 *
michael@0 24 * extraStartFunction (optional)
michael@0 25 * The function to call at the beginning of the defaultCallback function. If
michael@0 26 * the function returns true the defaultCallback function will return early
michael@0 27 * which allows waiting for a specific condition to be evaluated in the
michael@0 28 * function specified in the extraStartFunction property before continuing
michael@0 29 * with the test.
michael@0 30 *
michael@0 31 * extraCheckFunction (optional)
michael@0 32 * The function to call to perform extra checks in the defaultCallback
michael@0 33 * function.
michael@0 34 *
michael@0 35 * extraDelayedCheckFunction (optional)
michael@0 36 * The function to call to perform extra checks in the delayedDefaultCallback
michael@0 37 * function.
michael@0 38 *
michael@0 39 * buttonStates (optional)
michael@0 40 * A javascript object representing the expected hidden and disabled attribute
michael@0 41 * values for the buttons of the current wizard page. The values are checked
michael@0 42 * in the delayedDefaultCallback function. For information about the structure
michael@0 43 * of this object refer to the getExpectedButtonStates and checkButtonStates
michael@0 44 * functions.
michael@0 45 *
michael@0 46 * buttonClick (optional)
michael@0 47 * The current wizard page button to click at the end of the
michael@0 48 * delayedDefaultCallback function. If the buttonClick property is defined
michael@0 49 * then the extraDelayedFinishFunction property can't be specified due to race
michael@0 50 * conditions in some of the tests and if both of them are specified the test
michael@0 51 * will intentionally throw.
michael@0 52 *
michael@0 53 * extraDelayedFinishFunction (optional)
michael@0 54 * The function to call at the end of the delayedDefaultCallback function.
michael@0 55 * If the extraDelayedFinishFunction property is defined then the buttonClick
michael@0 56 * property can't be specified due to race conditions in some of the tests and
michael@0 57 * if both of them are specified the test will intentionally throw.
michael@0 58 *
michael@0 59 * ranTest (should not be specified)
michael@0 60 * When delayedDefaultCallback is called a property named ranTest is added to
michael@0 61 * the current test so it is possible to verify that each test in the TESTS
michael@0 62 * array has ran.
michael@0 63 *
michael@0 64 * prefHasUserValue (optional)
michael@0 65 * For comparing the expected value defined by this property with the return
michael@0 66 * value of prefHasUserValue using gPrefToCheck for the preference name in the
michael@0 67 * checkPrefHasUserValue function.
michael@0 68 *
michael@0 69 * expectedRadioGroupSelectedIndex (optional)
michael@0 70 * For comparing the expected selectedIndex attribute value of the wizard's
michael@0 71 * license page radiogroup selectedIndex attribute in the
michael@0 72 * checkRadioGroupSelectedIndex function.
michael@0 73 *
michael@0 74 * expectedRemoteContentState (optional)
michael@0 75 * For comparing the expected remotecontent state attribute value of the
michael@0 76 * wizard's billboard and license pages in the checkRemoteContentState and
michael@0 77 * waitForRemoteContentLoaded functions.
michael@0 78 *
michael@0 79 *
michael@0 80 * Test Add-ons
michael@0 81 *
michael@0 82 * All tests include the test add-ons specified in the TEST_ADDONS array and
michael@0 83 * the only thing that can be configured is whether the noupdate test add-on is
michael@0 84 * disabled (see below). The add-on names are in the format of typename_X where
michael@0 85 * X is a number to make the add-on ID unique and typename is one of the values
michael@0 86 * specified below:
michael@0 87 *
michael@0 88 * appdisabled
michael@0 89 * disabled by the application due to being incompatible with the current
michael@0 90 * toolkit version.
michael@0 91 *
michael@0 92 * compatible
michael@0 93 * compatible with the current toolkit version and the update's toolkit
michael@0 94 * version.
michael@0 95 *
michael@0 96 * noupdate
michael@0 97 * the add-on is compatible with the current toolkit version and does not have
michael@0 98 * an update to make it compatible with the update's toolkit version. Tests
michael@0 99 * that need to have all add-ons compatible for the application update can
michael@0 100 * disable this add-on by setting the gDisableNoUpdateAddon variable to true.
michael@0 101 *
michael@0 102 * updatecompatibility
michael@0 103 * the add-on is compatible with the current toolkit version and has a
michael@0 104 * compatibility update to make it compatible with the update's toolkit
michael@0 105 * version.
michael@0 106 *
michael@0 107 * updateversion
michael@0 108 * the add-on is compatible with the current toolkit version and has a version
michael@0 109 * update to make it compatible with the update's toolkit version.
michael@0 110 *
michael@0 111 * userdisabled
michael@0 112 * disabled by the user and compatible with the current toolkit version but
michael@0 113 * not the update's toolkit version. This add-on will be disabled after its
michael@0 114 * install completes.
michael@0 115 */
michael@0 116
michael@0 117 Components.utils.import("resource://gre/modules/AddonManager.jsm");
michael@0 118
michael@0 119 // The tests have to use the pageid instead of the pageIndex due to the
michael@0 120 // app update wizard's access method being random.
michael@0 121 const PAGEID_DUMMY = "dummy"; // Done
michael@0 122 const PAGEID_CHECKING = "checking"; // Done
michael@0 123 const PAGEID_PLUGIN_UPDATES = "pluginupdatesfound";
michael@0 124 const PAGEID_NO_UPDATES_FOUND = "noupdatesfound"; // Done
michael@0 125 const PAGEID_MANUAL_UPDATE = "manualUpdate"; // Tested on license load failure
michael@0 126 const PAGEID_UNSUPPORTED = "unsupported"; // Done
michael@0 127 const PAGEID_INCOMPAT_CHECK = "incompatibleCheck"; // Done
michael@0 128 const PAGEID_FOUND_BASIC = "updatesfoundbasic"; // Done
michael@0 129 const PAGEID_FOUND_BILLBOARD = "updatesfoundbillboard"; // Done
michael@0 130 const PAGEID_LICENSE = "license"; // Done
michael@0 131 const PAGEID_INCOMPAT_LIST = "incompatibleList"; // Done
michael@0 132 const PAGEID_DOWNLOADING = "downloading"; // Done
michael@0 133 const PAGEID_ERRORS = "errors"; // Done
michael@0 134 const PAGEID_ERROR_EXTRA = "errorextra"; // Done
michael@0 135 const PAGEID_ERROR_PATCHING = "errorpatching"; // Done
michael@0 136 const PAGEID_FINISHED = "finished"; // Done
michael@0 137 const PAGEID_FINISHED_BKGRD = "finishedBackground"; // Done
michael@0 138 const PAGEID_INSTALLED = "installed"; // Done
michael@0 139
michael@0 140 const UPDATE_WINDOW_NAME = "Update:Wizard";
michael@0 141
michael@0 142 const URL_HOST = "http://example.com";
michael@0 143 const URL_PATH_UPDATE_XML = "/chrome/toolkit/mozapps/update/tests/chrome/update.sjs";
michael@0 144 const REL_PATH_DATA = "chrome/toolkit/mozapps/update/tests/data";
michael@0 145
michael@0 146 const URL_HTTP_UPDATE_XML = URL_HOST + URL_PATH_UPDATE_XML;
michael@0 147 const URL_HTTPS_UPDATE_XML = "https://example.com" + URL_PATH_UPDATE_XML;
michael@0 148
michael@0 149 const URI_UPDATE_PROMPT_DIALOG = "chrome://mozapps/content/update/updates.xul";
michael@0 150
michael@0 151 const ADDON_ID_SUFFIX = "@appupdatetest.mozilla.org";
michael@0 152 const ADDON_PREP_DIR = "appupdateprep";
michael@0 153 // Preference for storing add-ons that are disabled by the tests to prevent them
michael@0 154 // from interefering with the tests.
michael@0 155 const PREF_DISABLEDADDONS = "app.update.test.disabledAddons";
michael@0 156 const PREF_EM_HOTFIX_ID = "extensions.hotfix.id";
michael@0 157 const TEST_ADDONS = [ "appdisabled_1", "appdisabled_2",
michael@0 158 "compatible_1", "compatible_2",
michael@0 159 "noupdate_1", "noupdate_2",
michael@0 160 "updatecompatibility_1", "updatecompatibility_2",
michael@0 161 "updateversion_1", "updateversion_2",
michael@0 162 "userdisabled_1", "userdisabled_2", "hotfix" ];
michael@0 163
michael@0 164 var gURLData = URL_HOST + "/" + REL_PATH_DATA + "/";
michael@0 165
michael@0 166 var gTestTimeout = 240000; // 4 minutes
michael@0 167 var gTimeoutTimer;
michael@0 168
michael@0 169 // The number of SimpleTest.executeSoon calls to perform when waiting on an
michael@0 170 // update window to close before giving up.
michael@0 171 const CLOSE_WINDOW_TIMEOUT_MAXCOUNT = 10;
michael@0 172 // Counter for the SimpleTest.executeSoon when waiting on an update window to
michael@0 173 // close before giving up.
michael@0 174 var gCloseWindowTimeoutCounter = 0;
michael@0 175
michael@0 176 // The following vars are for restoring previous preference values (if present)
michael@0 177 // when the test finishes.
michael@0 178 var gAppUpdateEnabled; // app.update.enabled
michael@0 179 var gAppUpdateMetroEnabled; // app.update.metro.enabled
michael@0 180 var gAppUpdateServiceEnabled; // app.update.service.enabled
michael@0 181 var gAppUpdateStagingEnabled; // app.update.staging.enabled
michael@0 182 var gAppUpdateURLDefault; // app.update.url (default prefbranch)
michael@0 183 var gAppUpdateURL; // app.update.url.override
michael@0 184 var gExtUpdateURL; // extensions.update.url
michael@0 185
michael@0 186 var gTestCounter = -1;
michael@0 187 var gWin;
michael@0 188 var gDocElem;
michael@0 189 var gPrefToCheck;
michael@0 190 var gDisableNoUpdateAddon = false;
michael@0 191
michael@0 192 // Set to true to log additional information for debugging. To log additional
michael@0 193 // information for an individual test set DEBUG_AUS_TEST to true in the test's
michael@0 194 // onload function.
michael@0 195 var DEBUG_AUS_TEST = true;
michael@0 196
michael@0 197 #include ../shared.js
michael@0 198
michael@0 199 /**
michael@0 200 * The current test in TESTS array.
michael@0 201 */
michael@0 202 this.__defineGetter__("gTest", function() {
michael@0 203 return TESTS[gTestCounter];
michael@0 204 });
michael@0 205
michael@0 206 /**
michael@0 207 * The current test's callback. This will either return the callback defined in
michael@0 208 * the test's overrideCallback property or defaultCallback if the
michael@0 209 * overrideCallback property is undefined.
michael@0 210 */
michael@0 211 this.__defineGetter__("gCallback", function() {
michael@0 212 return gTest.overrideCallback ? gTest.overrideCallback
michael@0 213 : defaultCallback;
michael@0 214 });
michael@0 215
michael@0 216 /**
michael@0 217 * The remotecontent element for the current page if one exists or null if a
michael@0 218 * remotecontent element doesn't exist.
michael@0 219 */
michael@0 220 this.__defineGetter__("gRemoteContent", function() {
michael@0 221 switch (gTest.pageid) {
michael@0 222 case PAGEID_FOUND_BILLBOARD:
michael@0 223 return gWin.document.getElementById("updateMoreInfoContent");
michael@0 224 case PAGEID_LICENSE:
michael@0 225 return gWin.document.getElementById("licenseContent");
michael@0 226 }
michael@0 227 return null;
michael@0 228 });
michael@0 229
michael@0 230 /**
michael@0 231 * The state for the remotecontent element if one exists or null if a
michael@0 232 * remotecontent element doesn't exist.
michael@0 233 */
michael@0 234 this.__defineGetter__("gRemoteContentState", function() {
michael@0 235 if (gRemoteContent) {
michael@0 236 return gRemoteContent.getAttribute("state");
michael@0 237 }
michael@0 238 return null;
michael@0 239 });
michael@0 240
michael@0 241 /**
michael@0 242 * The radiogroup for the license page.
michael@0 243 */
michael@0 244 this.__defineGetter__("gAcceptDeclineLicense", function() {
michael@0 245 return gWin.document.getElementById("acceptDeclineLicense");
michael@0 246 });
michael@0 247
michael@0 248 /**
michael@0 249 * The listbox for the incompatibleList page.
michael@0 250 */
michael@0 251 this.__defineGetter__("gIncompatibleListbox", function() {
michael@0 252 return gWin.document.getElementById("incompatibleListbox");
michael@0 253 });
michael@0 254
michael@0 255 /**
michael@0 256 * Default test run function that can be used by most tests. This function uses
michael@0 257 * protective measures to prevent the test from failing provided by
michael@0 258 * |runTestDefaultWaitForWindowClosed| helper functions to prevent failure due
michael@0 259 * to a previous test failure.
michael@0 260 */
michael@0 261 function runTestDefault() {
michael@0 262 debugDump("entering");
michael@0 263
michael@0 264 if (!("@mozilla.org/zipwriter;1" in AUS_Cc)) {
michael@0 265 ok(false, "nsIZipWriter is required to run these tests");
michael@0 266 return;
michael@0 267 }
michael@0 268
michael@0 269 SimpleTest.waitForExplicitFinish();
michael@0 270
michael@0 271 runTestDefaultWaitForWindowClosed();
michael@0 272 }
michael@0 273
michael@0 274 /**
michael@0 275 * If an update window is found SimpleTest.executeSoon can callback before the
michael@0 276 * update window is fully closed especially with debug builds. If an update
michael@0 277 * window is found this function will call itself using SimpleTest.executeSoon
michael@0 278 * up to the amount declared in CLOSE_WINDOW_TIMEOUT_MAXCOUNT until the update
michael@0 279 * window has closed before continuing the test.
michael@0 280 */
michael@0 281 function runTestDefaultWaitForWindowClosed() {
michael@0 282 gCloseWindowTimeoutCounter++;
michael@0 283 if (gCloseWindowTimeoutCounter > CLOSE_WINDOW_TIMEOUT_MAXCOUNT) {
michael@0 284 try {
michael@0 285 finishTest();
michael@0 286 }
michael@0 287 catch (e) {
michael@0 288 finishTestDefault();
michael@0 289 }
michael@0 290 return;
michael@0 291 }
michael@0 292
michael@0 293 // The update window should not be open at this time. If it is the call to
michael@0 294 // |closeUpdateWindow| will close it and cause the test to fail.
michael@0 295 if (closeUpdateWindow()) {
michael@0 296 SimpleTest.executeSoon(runTestDefaultWaitForWindowClosed);
michael@0 297 }
michael@0 298 else {
michael@0 299 Services.ww.registerNotification(gWindowObserver);
michael@0 300
michael@0 301 gCloseWindowTimeoutCounter = 0;
michael@0 302
michael@0 303 setupFiles();
michael@0 304 setupPrefs();
michael@0 305 removeUpdateDirsAndFiles();
michael@0 306 reloadUpdateManagerData();
michael@0 307 setupAddons(runTest);
michael@0 308 }
michael@0 309 }
michael@0 310
michael@0 311 /**
michael@0 312 * Default test finish function that can be used by most tests. This function
michael@0 313 * uses protective measures to prevent the next test from failing provided by
michael@0 314 * |finishTestDefaultWaitForWindowClosed| helper functions to prevent failure
michael@0 315 * due to an update window being left open.
michael@0 316 */
michael@0 317 function finishTestDefault() {
michael@0 318 debugDump("entering");
michael@0 319 if (gTimeoutTimer) {
michael@0 320 gTimeoutTimer.cancel();
michael@0 321 gTimeoutTimer = null;
michael@0 322 }
michael@0 323
michael@0 324 if (gChannel) {
michael@0 325 debugDump("channel = " + gChannel);
michael@0 326 gChannel = null;
michael@0 327 gPrefRoot.removeObserver(PREF_APP_UPDATE_CHANNEL, observer);
michael@0 328 }
michael@0 329
michael@0 330 verifyTestsRan();
michael@0 331
michael@0 332 resetPrefs();
michael@0 333 resetFiles();
michael@0 334 removeUpdateDirsAndFiles();
michael@0 335 reloadUpdateManagerData();
michael@0 336
michael@0 337 Services.ww.unregisterNotification(gWindowObserver);
michael@0 338 if (gDocElem) {
michael@0 339 gDocElem.removeEventListener("pageshow", onPageShowDefault, false);
michael@0 340 }
michael@0 341
michael@0 342 finishTestDefaultWaitForWindowClosed();
michael@0 343 }
michael@0 344
michael@0 345 /**
michael@0 346 * nsITimerCallback for the timeout timer to cleanly finish a test if the Update
michael@0 347 * Window doesn't close for a test. This allows the next test to run properly if
michael@0 348 * a previous test fails.
michael@0 349 *
michael@0 350 * @param aTimer
michael@0 351 * The nsITimer that fired.
michael@0 352 */
michael@0 353 function finishTestTimeout(aTimer) {
michael@0 354 ok(false, "Test timed out. Maximum time allowed is " + (gTestTimeout / 1000) +
michael@0 355 " seconds");
michael@0 356
michael@0 357 try {
michael@0 358 finishTest();
michael@0 359 }
michael@0 360 catch (e) {
michael@0 361 finishTestDefault();
michael@0 362 }
michael@0 363 }
michael@0 364
michael@0 365 /**
michael@0 366 * If an update window is found SimpleTest.executeSoon can callback before the
michael@0 367 * update window is fully closed especially with debug builds. If an update
michael@0 368 * window is found this function will call itself using SimpleTest.executeSoon
michael@0 369 * up to the amount declared in CLOSE_WINDOW_TIMEOUT_MAXCOUNT until the update
michael@0 370 * window has closed before finishing the test.
michael@0 371 */
michael@0 372 function finishTestDefaultWaitForWindowClosed() {
michael@0 373 gCloseWindowTimeoutCounter++;
michael@0 374 if (gCloseWindowTimeoutCounter > CLOSE_WINDOW_TIMEOUT_MAXCOUNT) {
michael@0 375 SimpleTest.finish();
michael@0 376 return;
michael@0 377 }
michael@0 378
michael@0 379 // The update window should not be open at this time. If it is the call to
michael@0 380 // |closeUpdateWindow| will close it and cause the test to fail.
michael@0 381 if (closeUpdateWindow()) {
michael@0 382 SimpleTest.executeSoon(finishTestDefaultWaitForWindowClosed);
michael@0 383 }
michael@0 384 else {
michael@0 385 SimpleTest.finish();
michael@0 386 }
michael@0 387 }
michael@0 388
michael@0 389 /**
michael@0 390 * Default callback for the wizard's documentElement pageshow listener. This
michael@0 391 * will return early for event's where the originalTarget's nodeName is not
michael@0 392 * wizardpage.
michael@0 393 */
michael@0 394 function onPageShowDefault(aEvent) {
michael@0 395 if (!gTimeoutTimer) {
michael@0 396 debugDump("gTimeoutTimer is null... returning early");
michael@0 397 return;
michael@0 398 }
michael@0 399
michael@0 400 // Return early if the event's original target isn't for a wizardpage element.
michael@0 401 // This check is necessary due to the remotecontent element firing pageshow.
michael@0 402 if (aEvent.originalTarget.nodeName != "wizardpage") {
michael@0 403 debugDump("only handles events with an originalTarget nodeName of " +
michael@0 404 "|wizardpage|. aEvent.originalTarget.nodeName = " +
michael@0 405 aEvent.originalTarget.nodeName + "... returning early");
michael@0 406 return;
michael@0 407 }
michael@0 408
michael@0 409 gTestCounter++;
michael@0 410 gCallback(aEvent);
michael@0 411 }
michael@0 412
michael@0 413 /**
michael@0 414 * Default callback that can be used by most tests.
michael@0 415 */
michael@0 416 function defaultCallback(aEvent) {
michael@0 417 if (!gTimeoutTimer) {
michael@0 418 debugDump("gTimeoutTimer is null... returning early");
michael@0 419 return;
michael@0 420 }
michael@0 421
michael@0 422 debugDump("entering - TESTS[" + gTestCounter + "], pageid: " + gTest.pageid +
michael@0 423 ", aEvent.originalTarget.nodeName: " +
michael@0 424 aEvent.originalTarget.nodeName);
michael@0 425
michael@0 426 if (gTest && gTest.extraStartFunction) {
michael@0 427 debugDump("calling extraStartFunction " + gTest.extraStartFunction.name);
michael@0 428 if (gTest.extraStartFunction(aEvent)) {
michael@0 429 debugDump("extraStartFunction early return");
michael@0 430 return;
michael@0 431 }
michael@0 432 }
michael@0 433
michael@0 434 is(gDocElem.currentPage.pageid, gTest.pageid,
michael@0 435 "Checking currentPage.pageid equals " + gTest.pageid + " in pageshow");
michael@0 436
michael@0 437 // Perform extra checks if specified by the test
michael@0 438 if (gTest.extraCheckFunction) {
michael@0 439 debugDump("calling extraCheckFunction " + gTest.extraCheckFunction.name);
michael@0 440 gTest.extraCheckFunction();
michael@0 441 }
michael@0 442
michael@0 443 // The wizard page buttons' disabled and hidden attributes are set after the
michael@0 444 // pageshow event so use executeSoon to allow them to be set so their disabled
michael@0 445 // and hidden attribute values can be checked.
michael@0 446 SimpleTest.executeSoon(delayedDefaultCallback);
michael@0 447 }
michael@0 448
michael@0 449 /**
michael@0 450 * Delayed default callback called using executeSoon in defaultCallback which
michael@0 451 * allows the wizard page buttons' disabled and hidden attributes to be set
michael@0 452 * before checking their values.
michael@0 453 */
michael@0 454 function delayedDefaultCallback() {
michael@0 455 if (!gTimeoutTimer) {
michael@0 456 debugDump("gTimeoutTimer is null... returning early");
michael@0 457 return;
michael@0 458 }
michael@0 459
michael@0 460 if (!gTest) {
michael@0 461 debugDump("gTest is null... returning early");
michael@0 462 return;
michael@0 463 }
michael@0 464
michael@0 465 debugDump("entering - TESTS[" + gTestCounter + "], pageid: " + gTest.pageid);
michael@0 466
michael@0 467 // Verify the pageid hasn't changed after executeSoon was called.
michael@0 468 is(gDocElem.currentPage.pageid, gTest.pageid,
michael@0 469 "Checking currentPage.pageid equals " + gTest.pageid + " after " +
michael@0 470 "executeSoon");
michael@0 471
michael@0 472 checkButtonStates();
michael@0 473
michael@0 474 // Perform delayed extra checks if specified by the test
michael@0 475 if (gTest.extraDelayedCheckFunction) {
michael@0 476 debugDump("calling extraDelayedCheckFunction " +
michael@0 477 gTest.extraDelayedCheckFunction.name);
michael@0 478 gTest.extraDelayedCheckFunction();
michael@0 479 }
michael@0 480
michael@0 481 // Used to verify that this test has been performed
michael@0 482 gTest.ranTest = true;
michael@0 483
michael@0 484 if (gTest.buttonClick) {
michael@0 485 debugDump("clicking " + gTest.buttonClick + " button");
michael@0 486 if(gTest.extraDelayedFinishFunction) {
michael@0 487 throw("Tests cannot have a buttonClick and an extraDelayedFinishFunction property");
michael@0 488 }
michael@0 489 gDocElem.getButton(gTest.buttonClick).click();
michael@0 490 }
michael@0 491 else if (gTest.extraDelayedFinishFunction) {
michael@0 492 debugDump("calling extraDelayedFinishFunction " +
michael@0 493 gTest.extraDelayedFinishFunction.name);
michael@0 494 gTest.extraDelayedFinishFunction();
michael@0 495 }
michael@0 496 }
michael@0 497
michael@0 498 /**
michael@0 499 * Checks the wizard page buttons' disabled and hidden attributes values are
michael@0 500 * correct. If an expected button id is not specified then the expected disabled
michael@0 501 * and hidden attribute value is true.
michael@0 502 */
michael@0 503 function checkButtonStates() {
michael@0 504 debugDump("entering - TESTS[" + gTestCounter + "], pageid: " + gTest.pageid);
michael@0 505
michael@0 506 const buttonNames = ["extra1", "extra2", "back", "next", "finish", "cancel"];
michael@0 507 let buttonStates = getExpectedButtonStates();
michael@0 508 buttonNames.forEach(function(aButtonName) {
michael@0 509 let button = gDocElem.getButton(aButtonName);
michael@0 510 let hasHidden = aButtonName in buttonStates &&
michael@0 511 "hidden" in buttonStates[aButtonName];
michael@0 512 let hidden = hasHidden ? buttonStates[aButtonName].hidden : true;
michael@0 513 let hasDisabled = aButtonName in buttonStates &&
michael@0 514 "disabled" in buttonStates[aButtonName];
michael@0 515 let disabled = hasDisabled ? buttonStates[aButtonName].disabled : true;
michael@0 516 is(button.hidden, hidden, "Checking " + aButtonName + " button " +
michael@0 517 "hidden attribute value equals " + (hidden ? "true" : "false"));
michael@0 518 is(button.disabled, disabled, "Checking " + aButtonName + " button " +
michael@0 519 "disabled attribute value equals " + (disabled ? "true" : "false"));
michael@0 520 });
michael@0 521 }
michael@0 522
michael@0 523 /**
michael@0 524 * Returns the expected disabled and hidden attribute values for the buttons of
michael@0 525 * the current wizard page.
michael@0 526 */
michael@0 527 function getExpectedButtonStates() {
michael@0 528 // Allow individual tests to override the expected button states.
michael@0 529 if (gTest.buttonStates) {
michael@0 530 return gTest.buttonStates;
michael@0 531 }
michael@0 532
michael@0 533 switch (gTest.pageid) {
michael@0 534 case PAGEID_CHECKING:
michael@0 535 case PAGEID_INCOMPAT_CHECK:
michael@0 536 return { cancel: { disabled: false, hidden: false } };
michael@0 537 case PAGEID_FOUND_BASIC:
michael@0 538 case PAGEID_FOUND_BILLBOARD:
michael@0 539 if (gTest.neverButton) {
michael@0 540 return { extra1: { disabled: false, hidden: false },
michael@0 541 extra2: { disabled: false, hidden: false },
michael@0 542 next : { disabled: false, hidden: false } }
michael@0 543 }
michael@0 544 return { extra1: { disabled: false, hidden: false },
michael@0 545 next : { disabled: false, hidden: false } };
michael@0 546 case PAGEID_LICENSE:
michael@0 547 if (gRemoteContentState != "loaded" ||
michael@0 548 gAcceptDeclineLicense.selectedIndex != 0) {
michael@0 549 return { extra1: { disabled: false, hidden: false },
michael@0 550 next : { disabled: true, hidden: false } };
michael@0 551 }
michael@0 552 return { extra1: { disabled: false, hidden: false },
michael@0 553 next : { disabled: false, hidden: false } };
michael@0 554 case PAGEID_INCOMPAT_LIST:
michael@0 555 return { extra1: { disabled: false, hidden: false },
michael@0 556 next : { disabled: false, hidden: false } };
michael@0 557 case PAGEID_DOWNLOADING:
michael@0 558 return { extra1: { disabled: false, hidden: false } };
michael@0 559 case PAGEID_NO_UPDATES_FOUND:
michael@0 560 case PAGEID_MANUAL_UPDATE:
michael@0 561 case PAGEID_UNSUPPORTED:
michael@0 562 case PAGEID_ERRORS:
michael@0 563 case PAGEID_ERROR_EXTRA:
michael@0 564 case PAGEID_INSTALLED:
michael@0 565 return { finish: { disabled: false, hidden: false } };
michael@0 566 case PAGEID_ERROR_PATCHING:
michael@0 567 return { next : { disabled: false, hidden: false } };
michael@0 568 case PAGEID_FINISHED:
michael@0 569 case PAGEID_FINISHED_BKGRD:
michael@0 570 return { extra1: { disabled: false, hidden: false },
michael@0 571 finish: { disabled: false, hidden: false } };
michael@0 572 }
michael@0 573 return null;
michael@0 574 }
michael@0 575
michael@0 576 /**
michael@0 577 * Adds a load event listener to the current remotecontent element.
michael@0 578 */
michael@0 579 function addRemoteContentLoadListener() {
michael@0 580 debugDump("entering - TESTS[" + gTestCounter + "], pageid: " + gTest.pageid);
michael@0 581
michael@0 582 gRemoteContent.addEventListener("load", remoteContentLoadListener, false);
michael@0 583 }
michael@0 584
michael@0 585 /**
michael@0 586 * The nsIDOMEventListener for a remotecontent load event.
michael@0 587 */
michael@0 588 function remoteContentLoadListener(aEvent) {
michael@0 589 // Return early if the event's original target's nodeName isn't remotecontent.
michael@0 590 if (aEvent.originalTarget.nodeName != "remotecontent") {
michael@0 591 debugDump("only handles events with an originalTarget nodeName of " +
michael@0 592 "|remotecontent|. aEvent.originalTarget.nodeName = " +
michael@0 593 aEvent.originalTarget.nodeName);
michael@0 594 return;
michael@0 595 }
michael@0 596
michael@0 597 gTestCounter++;
michael@0 598 gCallback(aEvent);
michael@0 599 }
michael@0 600
michael@0 601 /**
michael@0 602 * Waits until a remotecontent element to finish loading which is determined
michael@0 603 * by the current test's expectedRemoteContentState property and then removes
michael@0 604 * the event listener.
michael@0 605 *
michael@0 606 * Note: tests that use this function should not test the state of the
michael@0 607 * remotecontent since this will check the expected state.
michael@0 608 *
michael@0 609 * @return false if the remotecontent has loaded and its state is the state
michael@0 610 * specified in the current test's expectedRemoteContentState
michael@0 611 * property... otherwise true.
michael@0 612 */
michael@0 613 function waitForRemoteContentLoaded(aEvent) {
michael@0 614 // Return early until the remotecontent has loaded with the state that is
michael@0 615 // expected or isn't the event's originalTarget.
michael@0 616 if (gRemoteContentState != gTest.expectedRemoteContentState ||
michael@0 617 aEvent.originalTarget != gRemoteContent) {
michael@0 618 debugDump("returning early\n" +
michael@0 619 "gRemoteContentState: " + gRemoteContentState + "\n" +
michael@0 620 "expectedRemoteContentState: " +
michael@0 621 gTest.expectedRemoteContentState + "\n" +
michael@0 622 "aEvent.originalTarget.nodeName: " +
michael@0 623 aEvent.originalTarget.nodeName);
michael@0 624 return true;
michael@0 625 }
michael@0 626
michael@0 627 gRemoteContent.removeEventListener("load", remoteContentLoadListener, false);
michael@0 628 return false;
michael@0 629 }
michael@0 630
michael@0 631 /**
michael@0 632 * Compares the value of the remotecontent state attribute with the value
michael@0 633 * specified in the test's expectedRemoteContentState property.
michael@0 634 */
michael@0 635 function checkRemoteContentState() {
michael@0 636 is(gRemoteContentState, gTest.expectedRemoteContentState, "Checking remote " +
michael@0 637 "content state equals " + gTest.expectedRemoteContentState + " - pageid " +
michael@0 638 gTest.pageid);
michael@0 639 }
michael@0 640
michael@0 641 /**
michael@0 642 * Adds a select event listener to the license radiogroup element and clicks
michael@0 643 * the radio element specified in the current test's radioClick property.
michael@0 644 */
michael@0 645 function addRadioGroupSelectListenerAndClick() {
michael@0 646 debugDump("entering - TESTS[" + gTestCounter + "], pageid: " + gTest.pageid);
michael@0 647
michael@0 648 gAcceptDeclineLicense.addEventListener("select", radioGroupSelectListener,
michael@0 649 false);
michael@0 650 gWin.document.getElementById(gTest.radioClick).click();
michael@0 651 }
michael@0 652
michael@0 653 /**
michael@0 654 * The nsIDOMEventListener for the license radiogroup select event.
michael@0 655 */
michael@0 656 function radioGroupSelectListener(aEvent) {
michael@0 657 // Return early if the event's original target's nodeName isn't radiogroup.
michael@0 658 if (aEvent.originalTarget.nodeName != "radiogroup") {
michael@0 659 debugDump("only handles events with an originalTarget nodeName of " +
michael@0 660 "|radiogroup|. aEvent.originalTarget.nodeName = " +
michael@0 661 aEvent.originalTarget.nodeName);
michael@0 662 return;
michael@0 663 }
michael@0 664
michael@0 665 gAcceptDeclineLicense.removeEventListener("select", radioGroupSelectListener,
michael@0 666 false);
michael@0 667 gTestCounter++;
michael@0 668 gCallback(aEvent);
michael@0 669 }
michael@0 670
michael@0 671 /**
michael@0 672 * Compares the value of the License radiogroup's selectedIndex attribute with
michael@0 673 * the value specified in the test's expectedRadioGroupSelectedIndex property.
michael@0 674 */
michael@0 675 function checkRadioGroupSelectedIndex() {
michael@0 676 is(gAcceptDeclineLicense.selectedIndex, gTest.expectedRadioGroupSelectedIndex,
michael@0 677 "Checking license radiogroup selectedIndex equals " +
michael@0 678 gTest.expectedRadioGroupSelectedIndex);
michael@0 679 }
michael@0 680
michael@0 681 /**
michael@0 682 * Checks that only incompatible add-ons (e.g. noupdate_X add-ons) that don't
michael@0 683 * have an update are listed in the add-ons incompatible list.
michael@0 684 */
michael@0 685 function checkIncompatbleList() {
michael@0 686 for (let i = 0; i < gIncompatibleListbox.itemCount; i++) {
michael@0 687 let label = gIncompatibleListbox.getItemAtIndex(i).label;
michael@0 688 // Use indexOf since locales can change the text displayed
michael@0 689 ok(label.indexOf("noupdate") != -1, "Checking that only incompatible " +
michael@0 690 "add-ons that don't have an update are listed in the incompatible list");
michael@0 691 }
michael@0 692 }
michael@0 693
michael@0 694 /**
michael@0 695 * Compares the return value of prefHasUserValue for the preference specified in
michael@0 696 * gPrefToCheck with the value passed in the aPrefHasValue parameter or the
michael@0 697 * value specified in the current test's prefHasUserValue property if
michael@0 698 * aPrefHasValue is undefined.
michael@0 699 *
michael@0 700 * @param aPrefHasValue (optional)
michael@0 701 * The expected value returned from prefHasUserValue for the preference
michael@0 702 * specified in gPrefToCheck. If aPrefHasValue is undefined the value
michael@0 703 * of the current test's prefHasUserValue property will be used.
michael@0 704 */
michael@0 705 function checkPrefHasUserValue(aPrefHasValue) {
michael@0 706 let prefHasUserValue = aPrefHasValue === undefined ? gTest.prefHasUserValue
michael@0 707 : aPrefHasValue;
michael@0 708 is(Services.prefs.prefHasUserValue(gPrefToCheck), prefHasUserValue,
michael@0 709 "Checking prefHasUserValue for preference " + gPrefToCheck + " equals " +
michael@0 710 (prefHasUserValue ? "true" : "false"));
michael@0 711 }
michael@0 712
michael@0 713 /**
michael@0 714 * Checks whether the link is hidden (general background update check error or
michael@0 715 * a certificate attribute check error with an update) or not (certificate
michael@0 716 * attribute check error without an update) on the errorextra page and that the
michael@0 717 * app.update.cert.errors and app.update.backgroundErrors preferences do not
michael@0 718 & have a user value.
michael@0 719 *
michael@0 720 * @param aShouldBeHidden (optional)
michael@0 721 * The expected value for the label's hidden attribute for the link. If
michael@0 722 * aShouldBeHidden is undefined the value of the current test's
michael@0 723 * shouldBeHidden property will be used.
michael@0 724 */
michael@0 725 function checkErrorExtraPage(aShouldBeHidden) {
michael@0 726 let shouldBeHidden = aShouldBeHidden === undefined ? gTest.shouldBeHidden
michael@0 727 : aShouldBeHidden;
michael@0 728 is(gWin.document.getElementById("errorExtraLinkLabel").hidden, shouldBeHidden,
michael@0 729 "Checking errorExtraLinkLabel hidden attribute equals " +
michael@0 730 (shouldBeHidden ? "true" : "false"));
michael@0 731
michael@0 732 is(gWin.document.getElementById(gTest.displayedTextElem).hidden, false,
michael@0 733 "Checking " + gTest.displayedTextElem + " should not be hidden");
michael@0 734
michael@0 735 ok(!Services.prefs.prefHasUserValue(PREF_APP_UPDATE_CERT_ERRORS),
michael@0 736 "Preference " + PREF_APP_UPDATE_CERT_ERRORS + " should not have a " +
michael@0 737 "user value");
michael@0 738
michael@0 739 ok(!Services.prefs.prefHasUserValue(PREF_APP_UPDATE_BACKGROUNDERRORS),
michael@0 740 "Preference " + PREF_APP_UPDATE_BACKGROUNDERRORS + " should not have a " +
michael@0 741 "user value");
michael@0 742 }
michael@0 743
michael@0 744 /**
michael@0 745 * Gets the update version info for the update url parameters to send to
michael@0 746 * update.sjs.
michael@0 747 *
michael@0 748 * @param aAppVersion (optional)
michael@0 749 * The application version for the update snippet. If not specified the
michael@0 750 * current application version will be used.
michael@0 751 * @param aPlatformVersion (optional)
michael@0 752 * The platform version for the update snippet. If not specified the
michael@0 753 * current platform version will be used.
michael@0 754 * @return The url parameters for the application and platform version to send
michael@0 755 * to update.sjs.
michael@0 756 */
michael@0 757 function getVersionParams(aAppVersion, aPlatformVersion) {
michael@0 758 let appInfo = Services.appinfo;
michael@0 759 return "&appVersion=" + (aAppVersion ? aAppVersion : appInfo.version) +
michael@0 760 "&platformVersion=" + (aPlatformVersion ? aPlatformVersion
michael@0 761 : appInfo.platformVersion);
michael@0 762 }
michael@0 763
michael@0 764 /**
michael@0 765 * Gets an application version that is greater than the current application
michael@0 766 * version. The version is created by taking the first sequence from the current
michael@0 767 * application version and adding 1 to it.
michael@0 768 *
michael@0 769 * @return A version string greater than the current application version string.
michael@0 770 */
michael@0 771 function getNewerAppVersion() {
michael@0 772 let appVersion = Services.appinfo.version.split(".")[0];
michael@0 773 appVersion++;
michael@0 774 return appVersion;
michael@0 775 }
michael@0 776
michael@0 777 /**
michael@0 778 * Gets a platform version that is greater than the current platform version.
michael@0 779 * The version is created by taking the first sequence from the current platform
michael@0 780 * version and adding 1 to it.
michael@0 781 *
michael@0 782 * @return A version string greater than the current platform version string.
michael@0 783 */
michael@0 784 function getNewerPlatformVersion() {
michael@0 785 let platformVersion = Services.appinfo.platformVersion.split(".")[0];
michael@0 786 platformVersion++;
michael@0 787 return platformVersion;
michael@0 788 }
michael@0 789
michael@0 790 /**
michael@0 791 * Verifies that all tests ran.
michael@0 792 */
michael@0 793 function verifyTestsRan() {
michael@0 794 debugDump("entering");
michael@0 795
michael@0 796 // Return early if there are no tests defined.
michael@0 797 if (!TESTS) {
michael@0 798 return;
michael@0 799 }
michael@0 800
michael@0 801 gTestCounter = -1;
michael@0 802 for (let i = 0; i < TESTS.length; ++i) {
michael@0 803 gTestCounter++;
michael@0 804 let test = TESTS[i];
michael@0 805 let msg = "Checking if TESTS[" + i + "] test was performed... " +
michael@0 806 "callback function name = " + gCallback.name + ", " +
michael@0 807 "pageid = " + test.pageid;
michael@0 808 ok(test.ranTest, msg);
michael@0 809 }
michael@0 810 }
michael@0 811
michael@0 812 /**
michael@0 813 * Creates a backup of files the tests need to modify so they can be restored to
michael@0 814 * the original file when the test has finished and then modifies the files.
michael@0 815 */
michael@0 816 function setupFiles() {
michael@0 817 // Backup the updater-settings.ini file if it exists by moving it.
michael@0 818 let baseAppDir = getAppBaseDir();
michael@0 819 let updateSettingsIni = baseAppDir.clone();
michael@0 820 updateSettingsIni.append(FILE_UPDATE_SETTINGS_INI);
michael@0 821 if (updateSettingsIni.exists()) {
michael@0 822 updateSettingsIni.moveTo(baseAppDir, FILE_UPDATE_SETTINGS_INI_BAK);
michael@0 823 }
michael@0 824 updateSettingsIni = baseAppDir.clone();
michael@0 825 updateSettingsIni.append(FILE_UPDATE_SETTINGS_INI);
michael@0 826 writeFile(updateSettingsIni, UPDATE_SETTINGS_CONTENTS);
michael@0 827 }
michael@0 828
michael@0 829 /**
michael@0 830 * Sets the most common preferences used by tests to values used by the majority
michael@0 831 * of the tests and when necessary saves the preference's original values if
michael@0 832 * present so they can be set back to the original values when the test has
michael@0 833 * finished.
michael@0 834 */
michael@0 835 function setupPrefs() {
michael@0 836 if (DEBUG_AUS_TEST) {
michael@0 837 Services.prefs.setBoolPref(PREF_APP_UPDATE_LOG, true);
michael@0 838 }
michael@0 839
michael@0 840 if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_URL_OVERRIDE)) {
michael@0 841 gAppUpdateURL = Services.prefs.getCharPref(PREF_APP_UPDATE_URL_OVERRIDE);
michael@0 842 }
michael@0 843
michael@0 844 if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_ENABLED)) {
michael@0 845 gAppUpdateEnabled = Services.prefs.getBoolPref(PREF_APP_UPDATE_ENABLED);
michael@0 846 }
michael@0 847 Services.prefs.setBoolPref(PREF_APP_UPDATE_ENABLED, true);
michael@0 848
michael@0 849 if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_METRO_ENABLED)) {
michael@0 850 gAppUpdateMetroEnabled = Services.prefs.getBoolPref(PREF_APP_UPDATE_METRO_ENABLED);
michael@0 851 }
michael@0 852 Services.prefs.setBoolPref(PREF_APP_UPDATE_METRO_ENABLED, true);
michael@0 853
michael@0 854 if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_SERVICE_ENABLED)) {
michael@0 855 gAppUpdateServiceEnabled = Services.prefs.getBoolPref(PREF_APP_UPDATE_SERVICE_ENABLED);
michael@0 856 }
michael@0 857 Services.prefs.setBoolPref(PREF_APP_UPDATE_SERVICE_ENABLED, false);
michael@0 858
michael@0 859 if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_STAGING_ENABLED)) {
michael@0 860 gAppUpdateStagingEnabled = Services.prefs.getBoolPref(PREF_APP_UPDATE_STAGING_ENABLED);
michael@0 861 }
michael@0 862 Services.prefs.setBoolPref(PREF_APP_UPDATE_STAGING_ENABLED, false);
michael@0 863
michael@0 864 if (Services.prefs.prefHasUserValue(PREF_EXTENSIONS_UPDATE_URL)) {
michael@0 865 gExtUpdateURL = Services.prefs.getCharPref(PREF_EXTENSIONS_UPDATE_URL);
michael@0 866 }
michael@0 867 let extUpdateUrl = URL_HTTP_UPDATE_XML + "?addonID=%ITEM_ID%" +
michael@0 868 "&platformVersion=" + getNewerPlatformVersion();
michael@0 869 Services.prefs.setCharPref(PREF_EXTENSIONS_UPDATE_URL, extUpdateUrl);
michael@0 870
michael@0 871 Services.prefs.setIntPref(PREF_APP_UPDATE_IDLETIME, 0);
michael@0 872 Services.prefs.setIntPref(PREF_APP_UPDATE_PROMPTWAITTIME, 0);
michael@0 873 Services.prefs.setBoolPref(PREF_EXTENSIONS_STRICT_COMPAT, true);
michael@0 874 Services.prefs.setCharPref(PREF_EM_HOTFIX_ID, "hotfix" + ADDON_ID_SUFFIX);
michael@0 875 }
michael@0 876
michael@0 877 /**
michael@0 878 * Restores files that were backed up for the tests and general file cleanup.
michael@0 879 */
michael@0 880 function resetFiles() {
michael@0 881 // Restore the backed up updater-settings.ini if it exists.
michael@0 882 let baseAppDir = getAppBaseDir();
michael@0 883 let updateSettingsIni = baseAppDir.clone();
michael@0 884 updateSettingsIni.append(FILE_UPDATE_SETTINGS_INI_BAK);
michael@0 885 if (updateSettingsIni.exists()) {
michael@0 886 updateSettingsIni.moveTo(baseAppDir, FILE_UPDATE_SETTINGS_INI);
michael@0 887 }
michael@0 888
michael@0 889 // Not being able to remove the "updated" directory will not adversely affect
michael@0 890 // subsequent tests so wrap it in a try block and don't test whether its
michael@0 891 // removal was successful.
michael@0 892 let updatedDir = getUpdatedDir();
michael@0 893 if (updatedDir.exists()) {
michael@0 894 try {
michael@0 895 removeDirRecursive(updatedDir);
michael@0 896 }
michael@0 897 catch (e) {
michael@0 898 dump("Unable to remove directory\n" +
michael@0 899 "path: " + updatedDir.path + "\n" +
michael@0 900 "Exception: " + e + "\n");
michael@0 901 }
michael@0 902 }
michael@0 903 }
michael@0 904
michael@0 905 /**
michael@0 906 * Resets the most common preferences used by tests to their original values.
michael@0 907 */
michael@0 908 function resetPrefs() {
michael@0 909 if (gAppUpdateURL !== undefined) {
michael@0 910 Services.prefs.setCharPref(PREF_APP_UPDATE_URL_OVERRIDE, gAppUpdateURL);
michael@0 911 }
michael@0 912 else if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_URL_OVERRIDE)) {
michael@0 913 Services.prefs.clearUserPref(PREF_APP_UPDATE_URL_OVERRIDE);
michael@0 914 }
michael@0 915
michael@0 916 if (gAppUpdateURLDefault) {
michael@0 917 gDefaultPrefBranch.setCharPref(PREF_APP_UPDATE_URL, gAppUpdateURLDefault);
michael@0 918 }
michael@0 919
michael@0 920 if (gAppUpdateEnabled !== undefined) {
michael@0 921 Services.prefs.setBoolPref(PREF_APP_UPDATE_ENABLED, gAppUpdateEnabled);
michael@0 922 }
michael@0 923 else if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_ENABLED)) {
michael@0 924 Services.prefs.clearUserPref(PREF_APP_UPDATE_ENABLED);
michael@0 925 }
michael@0 926
michael@0 927 if (gAppUpdateMetroEnabled !== undefined) {
michael@0 928 Services.prefs.setBoolPref(PREF_APP_UPDATE_METRO_ENABLED, gAppUpdateMetroEnabled);
michael@0 929 }
michael@0 930 else if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_METRO_ENABLED)) {
michael@0 931 Services.prefs.clearUserPref(PREF_APP_UPDATE_METRO_ENABLED);
michael@0 932 }
michael@0 933
michael@0 934 if (gAppUpdateServiceEnabled !== undefined) {
michael@0 935 Services.prefs.setBoolPref(PREF_APP_UPDATE_SERVICE_ENABLED, gAppUpdateServiceEnabled);
michael@0 936 }
michael@0 937 else if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_SERVICE_ENABLED)) {
michael@0 938 Services.prefs.clearUserPref(PREF_APP_UPDATE_SERVICE_ENABLED);
michael@0 939 }
michael@0 940
michael@0 941 if (gAppUpdateStagingEnabled !== undefined) {
michael@0 942 Services.prefs.setBoolPref(PREF_APP_UPDATE_STAGING_ENABLED, gAppUpdateStagingEnabled);
michael@0 943 }
michael@0 944 else if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_STAGING_ENABLED)) {
michael@0 945 Services.prefs.clearUserPref(PREF_APP_UPDATE_STAGING_ENABLED);
michael@0 946 }
michael@0 947
michael@0 948 if (gExtUpdateURL !== undefined) {
michael@0 949 Services.prefs.setCharPref(PREF_EXTENSIONS_UPDATE_URL, gExtUpdateURL);
michael@0 950 }
michael@0 951 else if (Services.prefs.prefHasUserValue(PREF_EXTENSIONS_UPDATE_URL)) {
michael@0 952 Services.prefs.clearUserPref(PREF_EXTENSIONS_UPDATE_URL);
michael@0 953 }
michael@0 954
michael@0 955 if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_IDLETIME)) {
michael@0 956 Services.prefs.clearUserPref(PREF_APP_UPDATE_IDLETIME);
michael@0 957 }
michael@0 958
michael@0 959 if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_PROMPTWAITTIME)) {
michael@0 960 Services.prefs.clearUserPref(PREF_APP_UPDATE_PROMPTWAITTIME);
michael@0 961 }
michael@0 962
michael@0 963 if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_URL_DETAILS)) {
michael@0 964 Services.prefs.clearUserPref(PREF_APP_UPDATE_URL_DETAILS);
michael@0 965 }
michael@0 966
michael@0 967 if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_SHOW_INSTALLED_UI)) {
michael@0 968 Services.prefs.clearUserPref(PREF_APP_UPDATE_SHOW_INSTALLED_UI);
michael@0 969 }
michael@0 970
michael@0 971 if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_NOTIFIEDUNSUPPORTED)) {
michael@0 972 Services.prefs.clearUserPref(PREF_APP_UPDATE_NOTIFIEDUNSUPPORTED);
michael@0 973 }
michael@0 974
michael@0 975 if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_LOG)) {
michael@0 976 Services.prefs.clearUserPref(PREF_APP_UPDATE_LOG);
michael@0 977 }
michael@0 978
michael@0 979 if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_CERT_ERRORS)) {
michael@0 980 Services.prefs.clearUserPref(PREF_APP_UPDATE_CERT_ERRORS);
michael@0 981 }
michael@0 982
michael@0 983 if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_CERT_MAXERRORS)) {
michael@0 984 Services.prefs.clearUserPref(PREF_APP_UPDATE_CERT_MAXERRORS);
michael@0 985 }
michael@0 986
michael@0 987 if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_BACKGROUNDERRORS)) {
michael@0 988 Services.prefs.clearUserPref(PREF_APP_UPDATE_BACKGROUNDERRORS);
michael@0 989 }
michael@0 990
michael@0 991 if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_BACKGROUNDMAXERRORS)) {
michael@0 992 Services.prefs.clearUserPref(PREF_APP_UPDATE_BACKGROUNDMAXERRORS);
michael@0 993 }
michael@0 994
michael@0 995 if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_CERT_INVALID_ATTR_NAME)) {
michael@0 996 Services.prefs.clearUserPref(PREF_APP_UPDATE_CERT_INVALID_ATTR_NAME);
michael@0 997 }
michael@0 998
michael@0 999 if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_CERT_REQUIREBUILTIN)) {
michael@0 1000 Services.prefs.clearUserPref(PREF_APP_UPDATE_CERT_REQUIREBUILTIN);
michael@0 1001 }
michael@0 1002
michael@0 1003 if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_CERT_CHECKATTRS)) {
michael@0 1004 Services.prefs.clearUserPref(PREF_APP_UPDATE_CERT_CHECKATTRS);
michael@0 1005 }
michael@0 1006
michael@0 1007 try {
michael@0 1008 CERT_ATTRS.forEach(function(aCertAttrName) {
michael@0 1009 Services.prefs.clearUserPref(PREF_APP_UPDATE_CERTS_BRANCH + "1." +
michael@0 1010 aCertAttrName);
michael@0 1011 });
michael@0 1012 }
michael@0 1013 catch (e) {
michael@0 1014 }
michael@0 1015
michael@0 1016 try {
michael@0 1017 Services.prefs.deleteBranch(PREF_APP_UPDATE_NEVER_BRANCH);
michael@0 1018 }
michael@0 1019 catch(e) {
michael@0 1020 }
michael@0 1021
michael@0 1022 if (Services.prefs.prefHasUserValue(PREF_EXTENSIONS_STRICT_COMPAT)) {
michael@0 1023 Services.prefs.clearUserPref(PREF_EXTENSIONS_STRICT_COMPAT);
michael@0 1024 }
michael@0 1025
michael@0 1026 if (Services.prefs.prefHasUserValue(PREF_EM_HOTFIX_ID)) {
michael@0 1027 Services.prefs.clearUserPref(PREF_EM_HOTFIX_ID);
michael@0 1028 }
michael@0 1029 }
michael@0 1030
michael@0 1031 function setupTimer(aTestTimeout) {
michael@0 1032 gTestTimeout = aTestTimeout;
michael@0 1033 if (gTimeoutTimer) {
michael@0 1034 gTimeoutTimer.cancel();
michael@0 1035 gTimeoutTimer = null;
michael@0 1036 }
michael@0 1037 gTimeoutTimer = AUS_Cc["@mozilla.org/timer;1"].
michael@0 1038 createInstance(AUS_Ci.nsITimer);
michael@0 1039 gTimeoutTimer.initWithCallback(finishTestTimeout, gTestTimeout,
michael@0 1040 AUS_Ci.nsITimer.TYPE_ONE_SHOT);
michael@0 1041 }
michael@0 1042
michael@0 1043 /**
michael@0 1044 * Disables pre-existing add-ons so they don't interfere with the tests,
michael@0 1045 * installs the test add-ons, sets the noupdate test add-ons' userDisabled value
michael@0 1046 * for the test, and calls the callback specified in the aCallback parameter. If
michael@0 1047 * the app.update.test.disabledAddons has a user value then setting the noupdate
michael@0 1048 * test add-ons' userDisabled value for the test is the only thing that is done.
michael@0 1049 *
michael@0 1050 * @param aCallback
michael@0 1051 * A callback to call after all operations have completed.
michael@0 1052 */
michael@0 1053 function setupAddons(aCallback) {
michael@0 1054 debugDump("entering");
michael@0 1055
michael@0 1056 // Sets the appropriate userDisabled value for the noupdate test add-ons based
michael@0 1057 // on the value of gDisableNoUpdateAddon and calls the callback specified in
michael@0 1058 // setupAddons aCallback parameter.
michael@0 1059 function setNoUpdateAddonsDisabledState() {
michael@0 1060 AddonManager.getAllAddons(function(aAddons) {
michael@0 1061 aAddons.forEach(function(aAddon) {
michael@0 1062 if (aAddon.name.indexOf("noupdate") != 0)
michael@0 1063 return;
michael@0 1064
michael@0 1065 if (gDisableNoUpdateAddon) {
michael@0 1066 if (!aAddon.userDisabled) {
michael@0 1067 aAddon.userDisabled = true;
michael@0 1068 }
michael@0 1069 }
michael@0 1070 else {
michael@0 1071 if (aAddon.userDisabled) {
michael@0 1072 aAddon.userDisabled = false;
michael@0 1073 }
michael@0 1074 }
michael@0 1075 });
michael@0 1076 // Start the timout timer before the update window is displayed so it can
michael@0 1077 // clean up tests that don't successfully display the update window.
michael@0 1078 setupTimer(gTestTimeout);
michael@0 1079 aCallback();
michael@0 1080 });
michael@0 1081 }
michael@0 1082
michael@0 1083 // If the app.update.test.disabledAddons preference exists the pre-existing
michael@0 1084 // add-ons have already been disabled so they don't interfere with the tests,
michael@0 1085 // the test add-ons have already been installed, and the only thing that needs
michael@0 1086 // to be done is setting the appropriate userDisabled value for the noupdate
michael@0 1087 // test add-ons.
michael@0 1088 if (Services.prefs.prefHasUserValue(PREF_DISABLEDADDONS)) {
michael@0 1089 setNoUpdateAddonsDisabledState();
michael@0 1090 return;
michael@0 1091 }
michael@0 1092
michael@0 1093 // Disable all pre-existing enabled addons so they don't interfere with the
michael@0 1094 // tests.
michael@0 1095 AddonManager.getAllAddons(function(aAddons) {
michael@0 1096 let disabledAddons = [];
michael@0 1097 aAddons.forEach(function(aAddon) {
michael@0 1098 // If an addon's type equals plugin it is skipped since
michael@0 1099 // checking plugins compatibility information isn't supported at this
michael@0 1100 // time (also see bug 566787). Also, SCOPE_APPLICATION add-ons are
michael@0 1101 // excluded by app update so there is no reason to disable them.
michael@0 1102 if (aAddon.type != "plugin" && !aAddon.appDisabled &&
michael@0 1103 !aAddon.userDisabled &&
michael@0 1104 aAddon.scope != AddonManager.SCOPE_APPLICATION) {
michael@0 1105 disabledAddons.push(aAddon);
michael@0 1106 aAddon.userDisabled = true;
michael@0 1107 }
michael@0 1108 });
michael@0 1109 // If there are no pre-existing add-ons the preference value will be an
michael@0 1110 // empty string.
michael@0 1111 Services.prefs.setCharPref(PREF_DISABLEDADDONS, disabledAddons.join(" "));
michael@0 1112
michael@0 1113 // Install the test add-ons.
michael@0 1114 let xpiFiles = getTestAddonXPIFiles();
michael@0 1115 let xpiCount = xpiFiles.length;
michael@0 1116 let installs = [];
michael@0 1117 xpiFiles.forEach(function(aFile) {
michael@0 1118 AddonManager.getInstallForFile(aFile, function(aInstall) {
michael@0 1119 if (!aInstall) {
michael@0 1120 throw "No AddonInstall created for " + aFile.path;
michael@0 1121 }
michael@0 1122
michael@0 1123 installs.push(aInstall);
michael@0 1124
michael@0 1125 if (--xpiCount == 0) {
michael@0 1126 let installCount = installs.length;
michael@0 1127 function installCompleted(aInstall) {
michael@0 1128 aInstall.removeListener(listener);
michael@0 1129
michael@0 1130 if (getAddonTestType(aInstall.addon.name) == "userdisabled") {
michael@0 1131 aInstall.addon.userDisabled = true;
michael@0 1132 }
michael@0 1133 if (--installCount == 0) {
michael@0 1134 setNoUpdateAddonsDisabledState();
michael@0 1135 }
michael@0 1136 }
michael@0 1137
michael@0 1138 let listener = {
michael@0 1139 onDownloadFailed: installCompleted,
michael@0 1140 onDownloadCancelled: installCompleted,
michael@0 1141 onInstallFailed: installCompleted,
michael@0 1142 onInstallCancelled: installCompleted,
michael@0 1143 onInstallEnded: installCompleted
michael@0 1144 };
michael@0 1145
michael@0 1146 installs.forEach(function(aInstall) {
michael@0 1147 aInstall.addListener(listener);
michael@0 1148 aInstall.install();
michael@0 1149 });
michael@0 1150 }
michael@0 1151 });
michael@0 1152 });
michael@0 1153 });
michael@0 1154 }
michael@0 1155
michael@0 1156 /**
michael@0 1157 * Uninstalls the test add-ons, enables add-ons that were disabled when the
michael@0 1158 * test started, and calls the callback specified in the aCallback parameter.
michael@0 1159 *
michael@0 1160 * @param aCallback
michael@0 1161 * A callback to call after all operations have completed.
michael@0 1162 */
michael@0 1163 function resetAddons(aCallback) {
michael@0 1164 debugDump("entering");
michael@0 1165 // If test_9999_cleanup.xul is ran by itself then the test add-ons will not
michael@0 1166 // have been installed and any pre-existing add-ons will not have been
michael@0 1167 // disabled so return early.
michael@0 1168 if (!Services.prefs.prefHasUserValue(PREF_DISABLEDADDONS)) {
michael@0 1169 debugDump("preference " + PREF_DISABLEDADDONS + " doesn't exist... " +
michael@0 1170 "returning early");
michael@0 1171 aCallback();
michael@0 1172 return;
michael@0 1173 }
michael@0 1174
michael@0 1175 // Uninstall the test add-ons.
michael@0 1176 let count = TEST_ADDONS.length;
michael@0 1177 function uninstallCompleted(aAddon) {
michael@0 1178 if (--count == 0) {
michael@0 1179 AddonManager.removeAddonListener(listener);
michael@0 1180
michael@0 1181 // Enable the pre-existing add-ons that were disabled so they wouldn't
michael@0 1182 // interfere with the tests.
michael@0 1183 let disabledAddons = Services.prefs.getCharPref(PREF_DISABLEDADDONS).split(" ");
michael@0 1184 Services.prefs.clearUserPref(PREF_DISABLEDADDONS);
michael@0 1185 AddonManager.getAllAddons(function(aAddons) {
michael@0 1186 aAddons.forEach(function(aAddon) {
michael@0 1187 if (disabledAddons.indexOf(aAddon.id)) {
michael@0 1188 aAddon.userDisabled = false;
michael@0 1189 }
michael@0 1190 });
michael@0 1191 aCallback();
michael@0 1192 });
michael@0 1193 }
michael@0 1194 }
michael@0 1195
michael@0 1196 let listener = {
michael@0 1197 onUninstalled: uninstallCompleted
michael@0 1198 };
michael@0 1199
michael@0 1200 AddonManager.addAddonListener(listener);
michael@0 1201 TEST_ADDONS.forEach(function(aName) {
michael@0 1202 AddonManager.getAddonByID(aName + ADDON_ID_SUFFIX, function(aAddon) {
michael@0 1203 aAddon.uninstall();
michael@0 1204 });
michael@0 1205 });
michael@0 1206 }
michael@0 1207
michael@0 1208 /**
michael@0 1209 * Helper function to get the string before the '_' character in an add-on's
michael@0 1210 * name or id which is used to determine the add-on test type used by the tests.
michael@0 1211 *
michael@0 1212 * @param aName
michael@0 1213 * The test add-on's name or id.
michael@0 1214 * @return The string before the '_' character in the string passed in the aName
michael@0 1215 * parameter.
michael@0 1216 */
michael@0 1217 function getAddonTestType(aName) {
michael@0 1218 return aName.split("_")[0];
michael@0 1219 }
michael@0 1220
michael@0 1221 /**
michael@0 1222 * Helper function to create add-on xpi files for the default test add-ons.
michael@0 1223 *
michael@0 1224 * @return An array with each member being an nsILocalFile for an add-on XPI
michael@0 1225 * file.
michael@0 1226 */
michael@0 1227 function getTestAddonXPIFiles() {
michael@0 1228 let addonPrepDir = Services.dirsvc.get(NS_APP_USER_PROFILE_50_DIR,
michael@0 1229 AUS_Ci.nsILocalFile);
michael@0 1230 addonPrepDir.append(ADDON_PREP_DIR);
michael@0 1231
michael@0 1232 let bootstrap = addonPrepDir.clone();
michael@0 1233 bootstrap.append("bootstrap.js");
michael@0 1234 // If a previous test has already created bootstrap.js don't create it again.
michael@0 1235 if (!bootstrap.exists()) {
michael@0 1236 let bootstrapContents = "function install(data, reason){ }\n" +
michael@0 1237 "function startup(data, reason){ }\n" +
michael@0 1238 "function shutdown(data, reason){ }\n" +
michael@0 1239 "function uninstall(data, reason){ }\n";
michael@0 1240 writeFile(bootstrap, bootstrapContents);
michael@0 1241 }
michael@0 1242
michael@0 1243 let installRDF = addonPrepDir.clone();
michael@0 1244 installRDF.append("install.rdf");
michael@0 1245
michael@0 1246 let xpiFiles = [];
michael@0 1247 TEST_ADDONS.forEach(function(aName) {
michael@0 1248 let xpiFile = addonPrepDir.clone();
michael@0 1249 xpiFile.append(aName + ".xpi");
michael@0 1250
michael@0 1251 if (installRDF.exists())
michael@0 1252 installRDF.remove(false);
michael@0 1253 writeFile(installRDF, getInstallRDFString(aName));
michael@0 1254 gZipW.open(xpiFile, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE);
michael@0 1255 gZipW.addEntryFile(installRDF.leafName,
michael@0 1256 AUS_Ci.nsIZipWriter.COMPRESSION_DEFAULT, installRDF,
michael@0 1257 false);
michael@0 1258 gZipW.addEntryFile(bootstrap.leafName,
michael@0 1259 AUS_Ci.nsIZipWriter.COMPRESSION_DEFAULT, bootstrap,
michael@0 1260 false);
michael@0 1261 gZipW.close();
michael@0 1262 xpiFiles.push(xpiFile);
michael@0 1263 });
michael@0 1264
michael@0 1265 return xpiFiles;
michael@0 1266 }
michael@0 1267
michael@0 1268 /**
michael@0 1269 * Helper function to gets the string representation of the contents of the
michael@0 1270 * add-on's install.rdf file.
michael@0 1271 *
michael@0 1272 * @param aName
michael@0 1273 * The string to use for the add-on's name which is also used to
michael@0 1274 * construct the local-part in RFC 5322 format of the add-on's ID.
michael@0 1275 * @return A string representation of the contents of the add-on's install.rdf
michael@0 1276 * file.
michael@0 1277 */
michael@0 1278 function getInstallRDFString(aName) {
michael@0 1279 let maxVersion = Services.appinfo.platformVersion;
michael@0 1280 switch (getAddonTestType(aName)) {
michael@0 1281 case "compatible":
michael@0 1282 maxVersion = getNewerPlatformVersion();
michael@0 1283 break;
michael@0 1284 case "appdisabled":
michael@0 1285 maxVersion = "0.1";
michael@0 1286 break;
michael@0 1287 }
michael@0 1288
michael@0 1289 return "<?xml version=\"1.0\"?>\n" +
michael@0 1290 "<RDF xmlns=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n" +
michael@0 1291 " xmlns:em=\"http://www.mozilla.org/2004/em-rdf#\">\n" +
michael@0 1292 " <Description about=\"urn:mozilla:install-manifest\">\n" +
michael@0 1293 " <em:id>" + aName + ADDON_ID_SUFFIX + "</em:id>\n" +
michael@0 1294 " <em:version>1.0</em:version>\n" +
michael@0 1295 " <em:bootstrap>true</em:bootstrap>\n" +
michael@0 1296 " <em:name>" + aName + "</em:name>\n" +
michael@0 1297 " <em:description>Test Description</em:description>\n" +
michael@0 1298 " <em:targetApplication>\n" +
michael@0 1299 " <Description>\n" +
michael@0 1300 " <em:id>toolkit@mozilla.org</em:id>\n" +
michael@0 1301 " <em:minVersion>undefined</em:minVersion>\n" +
michael@0 1302 " <em:maxVersion>" + maxVersion + "</em:maxVersion>\n" +
michael@0 1303 " </Description>\n" +
michael@0 1304 " </em:targetApplication>\n" +
michael@0 1305 " </Description>\n" +
michael@0 1306 "</RDF>";
michael@0 1307 }
michael@0 1308
michael@0 1309 /**
michael@0 1310 * Closes the update window if it is open and causes the test to fail if an
michael@0 1311 * update window is found.
michael@0 1312 *
michael@0 1313 * @return true if an update window was found, otherwise false.
michael@0 1314 */
michael@0 1315 function closeUpdateWindow() {
michael@0 1316 let updateWindow = getUpdateWindow();
michael@0 1317 if (!updateWindow)
michael@0 1318 return false;
michael@0 1319
michael@0 1320 ok(false, "Found an existing Update Window from the current or a previous " +
michael@0 1321 "test... attempting to close it.");
michael@0 1322 updateWindow.close();
michael@0 1323 return true;
michael@0 1324 }
michael@0 1325
michael@0 1326 /**
michael@0 1327 * Gets the update window.
michael@0 1328 *
michael@0 1329 * @return The nsIDOMWindow for the Update Window if it is open and null
michael@0 1330 * if it isn't.
michael@0 1331 */
michael@0 1332 function getUpdateWindow() {
michael@0 1333 return Services.wm.getMostRecentWindow(UPDATE_WINDOW_NAME);
michael@0 1334 }
michael@0 1335
michael@0 1336 /**
michael@0 1337 * Helper for background check errors.
michael@0 1338 */
michael@0 1339 var errorsPrefObserver = {
michael@0 1340 observedPref: null,
michael@0 1341 maxErrorPref: null,
michael@0 1342
michael@0 1343 /**
michael@0 1344 * Sets up a preference observer and sets the associated maximum errors
michael@0 1345 * preference used for background notification.
michael@0 1346 *
michael@0 1347 * @param aObservePref
michael@0 1348 * The preference to observe.
michael@0 1349 * @param aMaxErrorPref
michael@0 1350 * The maximum errors preference.
michael@0 1351 * @param aMaxErrorCount
michael@0 1352 * The value to set the app.update.cert.maxErrors preference to.
michael@0 1353 */
michael@0 1354 init: function(aObservePref, aMaxErrorPref, aMaxErrorCount) {
michael@0 1355 this.observedPref = aObservePref;
michael@0 1356 this.maxErrorPref = aMaxErrorPref;
michael@0 1357
michael@0 1358 let maxErrors = aMaxErrorCount ? aMaxErrorCount : 2;
michael@0 1359 Services.prefs.setIntPref(aMaxErrorPref, maxErrors);
michael@0 1360 Services.prefs.addObserver(aObservePref, this, false);
michael@0 1361 },
michael@0 1362
michael@0 1363 /**
michael@0 1364 * Preference observer for the preference specified in |this.observedPref|.
michael@0 1365 */
michael@0 1366 observe: function XPI_observe(aSubject, aTopic, aData) {
michael@0 1367 if (aData == this.observedPref) {
michael@0 1368 let errCount = Services.prefs.getIntPref(this.observedPref);
michael@0 1369 let errMax = Services.prefs.getIntPref(this.maxErrorPref);
michael@0 1370 if (errCount >= errMax) {
michael@0 1371 debugDump("removing pref observer");
michael@0 1372 Services.prefs.removeObserver(this.observedPref, this);
michael@0 1373 }
michael@0 1374 else {
michael@0 1375 debugDump("notifying AUS");
michael@0 1376 SimpleTest.executeSoon(function() {
michael@0 1377 gAUS.notify(null);
michael@0 1378 });
michael@0 1379 }
michael@0 1380 }
michael@0 1381 }
michael@0 1382 };
michael@0 1383
michael@0 1384 /**
michael@0 1385 * nsIObserver for receiving window open and close notifications.
michael@0 1386 */
michael@0 1387 var gWindowObserver = {
michael@0 1388 observe: function WO_observe(aSubject, aTopic, aData) {
michael@0 1389 let win = aSubject.QueryInterface(AUS_Ci.nsIDOMEventTarget);
michael@0 1390
michael@0 1391 if (aTopic == "domwindowclosed") {
michael@0 1392 if (win.location != URI_UPDATE_PROMPT_DIALOG) {
michael@0 1393 debugDump("domwindowclosed event for window not being tested - " +
michael@0 1394 "location: " + win.location + "... returning early");
michael@0 1395 return;
michael@0 1396 }
michael@0 1397 // Allow tests the ability to provide their own function (it must be
michael@0 1398 // named finishTest) for finishing the test.
michael@0 1399 try {
michael@0 1400 finishTest();
michael@0 1401 }
michael@0 1402 catch (e) {
michael@0 1403 finishTestDefault();
michael@0 1404 }
michael@0 1405 return;
michael@0 1406 }
michael@0 1407
michael@0 1408 win.addEventListener("load", function WO_observe_onLoad() {
michael@0 1409 win.removeEventListener("load", WO_observe_onLoad, false);
michael@0 1410 // Ignore windows other than the update UI window.
michael@0 1411 if (win.location != URI_UPDATE_PROMPT_DIALOG) {
michael@0 1412 debugDump("load event for window not being tested - location: " +
michael@0 1413 win.location + "... returning early");
michael@0 1414 return;
michael@0 1415 }
michael@0 1416
michael@0 1417 // The first wizard page should always be the dummy page.
michael@0 1418 let pageid = win.document.documentElement.currentPage.pageid;
michael@0 1419 if (pageid != PAGEID_DUMMY) {
michael@0 1420 // This should never happen but if it does this will provide a clue
michael@0 1421 // for diagnosing the cause.
michael@0 1422 ok(false, "Unexpected load event - pageid got: " + pageid +
michael@0 1423 ", expected: " + PAGEID_DUMMY + "... returning early");
michael@0 1424 return;
michael@0 1425 }
michael@0 1426
michael@0 1427 gWin = win;
michael@0 1428 gDocElem = gWin.document.documentElement;
michael@0 1429 gDocElem.addEventListener("pageshow", onPageShowDefault, false);
michael@0 1430 }, false);
michael@0 1431 }
michael@0 1432 };

mercurial