Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
michael@0 | 1 | /** |
michael@0 | 2 | * Import common SimpleTest methods so that they're usable in this window. |
michael@0 | 3 | */ |
michael@0 | 4 | var imports = [ "SimpleTest", "is", "isnot", "ise", "ok", "onerror", "todo", |
michael@0 | 5 | "todo_is", "todo_isnot" ]; |
michael@0 | 6 | for each (var name in imports) { |
michael@0 | 7 | window[name] = window.opener.wrappedJSObject[name]; |
michael@0 | 8 | } |
michael@0 | 9 | |
michael@0 | 10 | /** |
michael@0 | 11 | * Define global constants and variables. |
michael@0 | 12 | */ |
michael@0 | 13 | const NAV_NONE = 0; |
michael@0 | 14 | const NAV_BACK = 1; |
michael@0 | 15 | const NAV_FORWARD = 2; |
michael@0 | 16 | const NAV_URI = 3; |
michael@0 | 17 | const NAV_RELOAD = 4; |
michael@0 | 18 | |
michael@0 | 19 | var gExpectedEvents; // an array of events which are expected to |
michael@0 | 20 | // be triggered by this navigation |
michael@0 | 21 | var gUnexpectedEvents; // an array of event names which are NOT expected |
michael@0 | 22 | // to be triggered by this navigation |
michael@0 | 23 | var gFinalEvent; // true if the last expected event has fired |
michael@0 | 24 | var gUrisNotInBFCache = []; // an array of uri's which shouldn't be stored |
michael@0 | 25 | // in the bfcache |
michael@0 | 26 | var gNavType = NAV_NONE; // defines the most recent navigation type |
michael@0 | 27 | // executed by doPageNavigation |
michael@0 | 28 | var gOrigMaxTotalViewers = // original value of max_total_viewers, |
michael@0 | 29 | undefined; // to be restored at end of test |
michael@0 | 30 | |
michael@0 | 31 | var gExtractedPath = null; //used to cache file path for extracting files from a .jar file |
michael@0 | 32 | |
michael@0 | 33 | /** |
michael@0 | 34 | * The doPageNavigation() function performs page navigations asynchronously, |
michael@0 | 35 | * listens for specified events, and compares actual events with a list of |
michael@0 | 36 | * expected events. When all expected events have occurred, an optional |
michael@0 | 37 | * callback can be notified. The parameter passed to this function is an |
michael@0 | 38 | * object with the following properties: |
michael@0 | 39 | * |
michael@0 | 40 | * uri: if !undefined, the browser will navigate to this uri |
michael@0 | 41 | * |
michael@0 | 42 | * back: if true, the browser will execute goBack() |
michael@0 | 43 | * |
michael@0 | 44 | * forward: if true, the browser will execute goForward() |
michael@0 | 45 | * |
michael@0 | 46 | * reload: if true, the browser will execute reload() |
michael@0 | 47 | * |
michael@0 | 48 | * eventsToListenFor: an array containing one or more of the following event |
michael@0 | 49 | * types to listen for: "pageshow", "pagehide", "onload", |
michael@0 | 50 | * "onunload". If this property is undefined, only a |
michael@0 | 51 | * single "pageshow" events will be listened for. If this |
michael@0 | 52 | * property is explicitly empty, [], then no events will |
michael@0 | 53 | * be listened for. |
michael@0 | 54 | * |
michael@0 | 55 | * expectedEvents: an array of one or more expectedEvent objects, |
michael@0 | 56 | * corresponding to the events which are expected to be |
michael@0 | 57 | * fired for this navigation. Each object has the |
michael@0 | 58 | * following properties: |
michael@0 | 59 | * |
michael@0 | 60 | * type: one of the event type strings |
michael@0 | 61 | * title (optional): the title of the window the |
michael@0 | 62 | * event belongs to |
michael@0 | 63 | * persisted (optional): the event's expected |
michael@0 | 64 | * .persisted attribute |
michael@0 | 65 | * |
michael@0 | 66 | * This function will verify that events with the |
michael@0 | 67 | * specified properties are fired in the same order as |
michael@0 | 68 | * specified in the array. If .title or .persisted |
michael@0 | 69 | * properties for an expectedEvent are undefined, those |
michael@0 | 70 | * properties will not be verified for that particular |
michael@0 | 71 | * event. |
michael@0 | 72 | * |
michael@0 | 73 | * This property is ignored if eventsToListenFor is |
michael@0 | 74 | * undefined or []. |
michael@0 | 75 | * |
michael@0 | 76 | * preventBFCache: if true, an unload handler will be added to the loaded |
michael@0 | 77 | * page to prevent it from being bfcached. This property |
michael@0 | 78 | * has no effect when eventsToListenFor is []. |
michael@0 | 79 | * |
michael@0 | 80 | * onNavComplete: a callback which is notified after all expected events |
michael@0 | 81 | * have occurred, or after a timeout has elapsed. This |
michael@0 | 82 | * callback is not notified if eventsToListenFor is []. |
michael@0 | 83 | * |
michael@0 | 84 | * There must be an expectedEvent object for each event of the types in |
michael@0 | 85 | * eventsToListenFor which is triggered by this navigation. For example, if |
michael@0 | 86 | * eventsToListenFor = [ "pagehide", "pageshow" ], then expectedEvents |
michael@0 | 87 | * must contain an object for each pagehide and pageshow event which occurs as |
michael@0 | 88 | * a result of this navigation. |
michael@0 | 89 | */ |
michael@0 | 90 | function doPageNavigation(params) { |
michael@0 | 91 | // Parse the parameters. |
michael@0 | 92 | let back = params.back ? params.back : false; |
michael@0 | 93 | let forward = params.forward ? params.forward : false; |
michael@0 | 94 | let reload = params.reload ? params.reload : false; |
michael@0 | 95 | let uri = params.uri ? params.uri : false; |
michael@0 | 96 | let eventsToListenFor = typeof(params.eventsToListenFor) != "undefined" ? |
michael@0 | 97 | params.eventsToListenFor : ["pageshow"]; |
michael@0 | 98 | gExpectedEvents = typeof(params.eventsToListenFor) == "undefined" || |
michael@0 | 99 | eventsToListenFor.length == 0 ? undefined : params.expectedEvents; |
michael@0 | 100 | gUnexpectedEvents = typeof(params.eventsToListenFor) == "undefined" || |
michael@0 | 101 | eventsToListenFor.length == 0 ? undefined : params.unexpectedEvents; |
michael@0 | 102 | let preventBFCache = (typeof[params.preventBFCache] == "undefined") ? |
michael@0 | 103 | false : params.preventBFCache; |
michael@0 | 104 | let waitOnly = (typeof(params.waitForEventsOnly) == "boolean" |
michael@0 | 105 | && params.waitForEventsOnly); |
michael@0 | 106 | |
michael@0 | 107 | // Do some sanity checking on arguments. |
michael@0 | 108 | if (back && forward) |
michael@0 | 109 | throw "Can't specify both back and forward"; |
michael@0 | 110 | if (back && uri) |
michael@0 | 111 | throw "Can't specify both back and a uri"; |
michael@0 | 112 | if (forward && uri) |
michael@0 | 113 | throw "Can't specify both forward and a uri"; |
michael@0 | 114 | if (reload && (forward || back || uri)) |
michael@0 | 115 | throw "Can't specify reload and another navigation type"; |
michael@0 | 116 | if (!back && !forward && !uri && !reload && !waitOnly) |
michael@0 | 117 | throw "Must specify back or foward or reload or uri"; |
michael@0 | 118 | if (params.onNavComplete && eventsToListenFor.length == 0) |
michael@0 | 119 | throw "Can't use onNavComplete when eventsToListenFor == []"; |
michael@0 | 120 | if (params.preventBFCache && eventsToListenFor.length == 0) |
michael@0 | 121 | throw "Can't use preventBFCache when eventsToListenFor == []"; |
michael@0 | 122 | if (params.preventBFCache && waitOnly) |
michael@0 | 123 | throw "Can't prevent bfcaching when only waiting for events"; |
michael@0 | 124 | if (waitOnly && typeof(params.onNavComplete) == "undefined") |
michael@0 | 125 | throw "Must specify onNavComplete when specifying waitForEventsOnly"; |
michael@0 | 126 | if (waitOnly && (back || forward || reload || uri)) |
michael@0 | 127 | throw "Can't specify a navigation type when using waitForEventsOnly"; |
michael@0 | 128 | for each (let anEventType in eventsToListenFor) { |
michael@0 | 129 | let eventFound = false; |
michael@0 | 130 | if ( (anEventType == "pageshow") && (!gExpectedEvents) ) |
michael@0 | 131 | eventFound = true; |
michael@0 | 132 | for each (let anExpectedEvent in gExpectedEvents) { |
michael@0 | 133 | if (anExpectedEvent.type == anEventType) |
michael@0 | 134 | eventFound = true; |
michael@0 | 135 | } |
michael@0 | 136 | for each (let anExpectedEventType in gUnexpectedEvents) { |
michael@0 | 137 | if (anExpectedEventType == anEventType) |
michael@0 | 138 | eventFound = true; |
michael@0 | 139 | } |
michael@0 | 140 | if (!eventFound) |
michael@0 | 141 | throw "Event type " + anEventType + " is specified in " + |
michael@0 | 142 | "eventsToListenFor, but not in expectedEvents"; |
michael@0 | 143 | } |
michael@0 | 144 | |
michael@0 | 145 | // If the test explicitly sets .eventsToListenFor to [], don't wait for any |
michael@0 | 146 | // events. |
michael@0 | 147 | gFinalEvent = eventsToListenFor.length == 0 ? true : false; |
michael@0 | 148 | |
michael@0 | 149 | // Add an event listener for each type of event in the .eventsToListenFor |
michael@0 | 150 | // property of the input parameters. |
michael@0 | 151 | for each (let eventType in eventsToListenFor) { |
michael@0 | 152 | dump("TEST: registering a listener for " + eventType + " events\n"); |
michael@0 | 153 | TestWindow.getBrowser().addEventListener(eventType, pageEventListener, |
michael@0 | 154 | true); |
michael@0 | 155 | } |
michael@0 | 156 | |
michael@0 | 157 | // Perform the specified navigation. |
michael@0 | 158 | if (back) { |
michael@0 | 159 | gNavType = NAV_BACK; |
michael@0 | 160 | TestWindow.getBrowser().goBack(); |
michael@0 | 161 | } |
michael@0 | 162 | else if (forward) { |
michael@0 | 163 | gNavType = NAV_FORWARD; |
michael@0 | 164 | TestWindow.getBrowser().goForward(); |
michael@0 | 165 | } |
michael@0 | 166 | else if (uri) { |
michael@0 | 167 | gNavType = NAV_URI; |
michael@0 | 168 | TestWindow.getBrowser().loadURI(uri); |
michael@0 | 169 | } |
michael@0 | 170 | else if (reload) { |
michael@0 | 171 | gNavType = NAV_RELOAD; |
michael@0 | 172 | TestWindow.getBrowser().reload(); |
michael@0 | 173 | } |
michael@0 | 174 | else if (waitOnly) { |
michael@0 | 175 | gNavType = NAV_NONE; |
michael@0 | 176 | } |
michael@0 | 177 | else { |
michael@0 | 178 | throw "No valid navigation type passed to doPageNavigation!"; |
michael@0 | 179 | } |
michael@0 | 180 | |
michael@0 | 181 | // If we're listening for events and there is an .onNavComplete callback, |
michael@0 | 182 | // wait for all events to occur, and then call doPageNavigation_complete(). |
michael@0 | 183 | if (eventsToListenFor.length > 0 && params.onNavComplete) |
michael@0 | 184 | { |
michael@0 | 185 | waitForTrue( |
michael@0 | 186 | function() { return gFinalEvent; }, |
michael@0 | 187 | function() { |
michael@0 | 188 | doPageNavigation_complete(eventsToListenFor, params.onNavComplete, |
michael@0 | 189 | preventBFCache); |
michael@0 | 190 | } ); |
michael@0 | 191 | } |
michael@0 | 192 | } |
michael@0 | 193 | |
michael@0 | 194 | /** |
michael@0 | 195 | * Finish doPageNavigation(), by removing event listeners, adding an unload |
michael@0 | 196 | * handler if appropriate, and calling the onNavComplete callback. This |
michael@0 | 197 | * function is called after all the expected events for this navigation have |
michael@0 | 198 | * occurred. |
michael@0 | 199 | */ |
michael@0 | 200 | function doPageNavigation_complete(eventsToListenFor, onNavComplete, |
michael@0 | 201 | preventBFCache) { |
michael@0 | 202 | // Unregister our event listeners. |
michael@0 | 203 | dump("TEST: removing event listeners\n"); |
michael@0 | 204 | for each (let eventType in eventsToListenFor) { |
michael@0 | 205 | TestWindow.getBrowser().removeEventListener(eventType, pageEventListener, |
michael@0 | 206 | true); |
michael@0 | 207 | } |
michael@0 | 208 | |
michael@0 | 209 | // If the .preventBFCache property was set, add an empty unload handler to |
michael@0 | 210 | // prevent the page from being bfcached. |
michael@0 | 211 | let uri = TestWindow.getBrowser().currentURI.spec; |
michael@0 | 212 | if (preventBFCache) { |
michael@0 | 213 | TestWindow.getWindow().addEventListener("unload", function() { |
michael@0 | 214 | dump("TEST: Called dummy unload function to prevent page from " + |
michael@0 | 215 | "being bfcached.\n"); |
michael@0 | 216 | }, true); |
michael@0 | 217 | |
michael@0 | 218 | // Save the current uri in an array of uri's which shouldn't be |
michael@0 | 219 | // stored in the bfcache, for later verification. |
michael@0 | 220 | if (!(uri in gUrisNotInBFCache)) { |
michael@0 | 221 | gUrisNotInBFCache.push(uri); |
michael@0 | 222 | } |
michael@0 | 223 | } else if (gNavType == NAV_URI) { |
michael@0 | 224 | // If we're navigating to a uri and .preventBFCache was not |
michael@0 | 225 | // specified, splice it out of gUrisNotInBFCache if it's there. |
michael@0 | 226 | gUrisNotInBFCache.forEach( |
michael@0 | 227 | function(element, index, array) { |
michael@0 | 228 | if (element == uri) { |
michael@0 | 229 | array.splice(index, 1); |
michael@0 | 230 | } |
michael@0 | 231 | }, this); |
michael@0 | 232 | } |
michael@0 | 233 | |
michael@0 | 234 | // Notify the callback now that we're done. |
michael@0 | 235 | onNavComplete.call(); |
michael@0 | 236 | } |
michael@0 | 237 | |
michael@0 | 238 | /** |
michael@0 | 239 | * Allows a test to wait for page navigation events, and notify a |
michael@0 | 240 | * callback when they've all been received. This works exactly the |
michael@0 | 241 | * same as doPageNavigation(), except that no navigation is initiated. |
michael@0 | 242 | */ |
michael@0 | 243 | function waitForPageEvents(params) { |
michael@0 | 244 | params.waitForEventsOnly = true; |
michael@0 | 245 | doPageNavigation(params); |
michael@0 | 246 | } |
michael@0 | 247 | |
michael@0 | 248 | /** |
michael@0 | 249 | * The event listener which listens for expectedEvents. |
michael@0 | 250 | */ |
michael@0 | 251 | function pageEventListener(event) { |
michael@0 | 252 | try { |
michael@0 | 253 | dump("TEST: eventListener received a " + event.type + " event for page " + |
michael@0 | 254 | event.originalTarget.title + ", persisted=" + event.persisted + "\n"); |
michael@0 | 255 | } catch(e) { |
michael@0 | 256 | // Ignore any exception. |
michael@0 | 257 | } |
michael@0 | 258 | |
michael@0 | 259 | // If this page shouldn't be in the bfcache because it was previously |
michael@0 | 260 | // loaded with .preventBFCache, make sure that its pageshow event |
michael@0 | 261 | // has .persisted = false, even if the test doesn't explicitly test |
michael@0 | 262 | // for .persisted. |
michael@0 | 263 | if ( (event.type == "pageshow") && |
michael@0 | 264 | (gNavType == NAV_BACK || gNavType == NAV_FORWARD) ) { |
michael@0 | 265 | let uri = TestWindow.getBrowser().currentURI.spec; |
michael@0 | 266 | if (uri in gUrisNotInBFCache) { |
michael@0 | 267 | ok(!event.persisted, "pageshow event has .persisted = false, even " + |
michael@0 | 268 | "though it was loaded with .preventBFCache previously\n"); |
michael@0 | 269 | } |
michael@0 | 270 | } |
michael@0 | 271 | |
michael@0 | 272 | if (typeof(gUnexpectedEvents) != "undefined") { |
michael@0 | 273 | is(gUnexpectedEvents.indexOf(event.type), -1, |
michael@0 | 274 | "Should not get unexpected event " + event.type); |
michael@0 | 275 | } |
michael@0 | 276 | |
michael@0 | 277 | // If no expected events were specified, mark the final event as having been |
michael@0 | 278 | // triggered when a pageshow event is fired; this will allow |
michael@0 | 279 | // doPageNavigation() to return. |
michael@0 | 280 | if ((typeof(gExpectedEvents) == "undefined") && event.type == "pageshow") |
michael@0 | 281 | { |
michael@0 | 282 | setTimeout(function() { gFinalEvent = true; }, 0); |
michael@0 | 283 | return; |
michael@0 | 284 | } |
michael@0 | 285 | |
michael@0 | 286 | // If there are explicitly no expected events, but we receive one, it's an |
michael@0 | 287 | // error. |
michael@0 | 288 | if (gExpectedEvents.length == 0) { |
michael@0 | 289 | ok(false, "Unexpected event (" + event.type + ") occurred"); |
michael@0 | 290 | return; |
michael@0 | 291 | } |
michael@0 | 292 | |
michael@0 | 293 | // Grab the next expected event, and compare its attributes against the |
michael@0 | 294 | // actual event. |
michael@0 | 295 | let expected = gExpectedEvents.shift(); |
michael@0 | 296 | |
michael@0 | 297 | is(event.type, expected.type, |
michael@0 | 298 | "A " + expected.type + " event was expected, but a " + |
michael@0 | 299 | event.type + " event occurred"); |
michael@0 | 300 | |
michael@0 | 301 | if (typeof(expected.title) != "undefined") { |
michael@0 | 302 | ok(event.originalTarget instanceof HTMLDocument, |
michael@0 | 303 | "originalTarget for last " + event.type + |
michael@0 | 304 | " event not an HTMLDocument"); |
michael@0 | 305 | is(event.originalTarget.title, expected.title, |
michael@0 | 306 | "A " + event.type + " event was expected for page " + |
michael@0 | 307 | expected.title + ", but was fired for page " + |
michael@0 | 308 | event.originalTarget.title); |
michael@0 | 309 | } |
michael@0 | 310 | |
michael@0 | 311 | if (typeof(expected.persisted) != "undefined") { |
michael@0 | 312 | is(event.persisted, expected.persisted, |
michael@0 | 313 | "The persisted property of the " + event.type + " event on page " + |
michael@0 | 314 | event.originalTarget.location + " had an unexpected value"); |
michael@0 | 315 | } |
michael@0 | 316 | |
michael@0 | 317 | if ("visibilityState" in expected) { |
michael@0 | 318 | is(event.originalTarget.visibilityState, expected.visibilityState, |
michael@0 | 319 | "The visibilityState property of the document on page " + |
michael@0 | 320 | event.originalTarget.location + " had an unexpected value"); |
michael@0 | 321 | } |
michael@0 | 322 | |
michael@0 | 323 | if ("hidden" in expected) { |
michael@0 | 324 | is(event.originalTarget.hidden, expected.hidden, |
michael@0 | 325 | "The hidden property of the document on page " + |
michael@0 | 326 | event.originalTarget.location + " had an unexpected value"); |
michael@0 | 327 | } |
michael@0 | 328 | |
michael@0 | 329 | // If we're out of expected events, let doPageNavigation() return. |
michael@0 | 330 | if (gExpectedEvents.length == 0) |
michael@0 | 331 | setTimeout(function() { gFinalEvent = true; }, 0); |
michael@0 | 332 | } |
michael@0 | 333 | |
michael@0 | 334 | /** |
michael@0 | 335 | * End a test. |
michael@0 | 336 | */ |
michael@0 | 337 | function finish() { |
michael@0 | 338 | // Work around bug 467960. |
michael@0 | 339 | var history = TestWindow.getBrowser().webNavigation.sessionHistory; |
michael@0 | 340 | history.PurgeHistory(history.count); |
michael@0 | 341 | |
michael@0 | 342 | // If the test changed the value of max_total_viewers via a call to |
michael@0 | 343 | // enableBFCache(), then restore it now. |
michael@0 | 344 | if (typeof(gOrigMaxTotalViewers) != "undefined") { |
michael@0 | 345 | var prefs = Components.classes["@mozilla.org/preferences-service;1"] |
michael@0 | 346 | .getService(Components.interfaces.nsIPrefBranch); |
michael@0 | 347 | prefs.setIntPref("browser.sessionhistory.max_total_viewers", |
michael@0 | 348 | gOrigMaxTotalViewers); |
michael@0 | 349 | } |
michael@0 | 350 | |
michael@0 | 351 | // Close the test window and signal the framework that the test is done. |
michael@0 | 352 | let opener = window.opener; |
michael@0 | 353 | let SimpleTest = opener.wrappedJSObject.SimpleTest; |
michael@0 | 354 | |
michael@0 | 355 | // Wait for the window to be closed before finishing the test |
michael@0 | 356 | let ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"] |
michael@0 | 357 | .getService(Components.interfaces.nsIWindowWatcher); |
michael@0 | 358 | ww.registerNotification(function(subject, topic, data) { |
michael@0 | 359 | if (topic == "domwindowclosed") { |
michael@0 | 360 | ww.unregisterNotification(arguments.callee); |
michael@0 | 361 | SimpleTest.waitForFocus(function() { |
michael@0 | 362 | SimpleTest.finish(); |
michael@0 | 363 | }, opener); |
michael@0 | 364 | } |
michael@0 | 365 | }); |
michael@0 | 366 | |
michael@0 | 367 | window.close(); |
michael@0 | 368 | } |
michael@0 | 369 | |
michael@0 | 370 | /** |
michael@0 | 371 | * Helper function which waits until another function returns true, or until a |
michael@0 | 372 | * timeout occurs, and then notifies a callback. |
michael@0 | 373 | * |
michael@0 | 374 | * Parameters: |
michael@0 | 375 | * |
michael@0 | 376 | * fn: a function which is evaluated repeatedly, and when it turns true, |
michael@0 | 377 | * the onWaitComplete callback is notified. |
michael@0 | 378 | * |
michael@0 | 379 | * onWaitComplete: a callback which will be notified when fn() returns |
michael@0 | 380 | * true, or when a timeout occurs. |
michael@0 | 381 | * |
michael@0 | 382 | * timeout: a timeout, in seconds or ms, after which waitForTrue() will |
michael@0 | 383 | * fail an assertion and then return, even if the fn function never |
michael@0 | 384 | * returns true. If timeout is undefined, waitForTrue() will never |
michael@0 | 385 | * time out. |
michael@0 | 386 | */ |
michael@0 | 387 | function waitForTrue(fn, onWaitComplete, timeout) { |
michael@0 | 388 | var start = new Date().valueOf(); |
michael@0 | 389 | if (typeof(timeout) != "undefined") { |
michael@0 | 390 | // If timeoutWait is less than 500, assume it represents seconds, and |
michael@0 | 391 | // convert to ms. |
michael@0 | 392 | if (timeout < 500) |
michael@0 | 393 | timeout *= 1000; |
michael@0 | 394 | } |
michael@0 | 395 | |
michael@0 | 396 | // Loop until the test function returns true, or until a timeout occurs, |
michael@0 | 397 | // if a timeout is defined. |
michael@0 | 398 | var intervalid; |
michael@0 | 399 | intervalid = |
michael@0 | 400 | setInterval( |
michael@0 | 401 | function() { |
michael@0 | 402 | var timeoutHit = false; |
michael@0 | 403 | if (typeof(timeout) != "undefined") { |
michael@0 | 404 | timeoutHit = new Date().valueOf() - start >= |
michael@0 | 405 | timeout ? true : false; |
michael@0 | 406 | if (timeoutHit) { |
michael@0 | 407 | ok(false, "Timed out waiting for condition"); |
michael@0 | 408 | } |
michael@0 | 409 | } |
michael@0 | 410 | if (timeoutHit || fn.call()) { |
michael@0 | 411 | // Stop calling the test function and notify the callback. |
michael@0 | 412 | clearInterval(intervalid); |
michael@0 | 413 | onWaitComplete.call(); |
michael@0 | 414 | } |
michael@0 | 415 | }, 20); |
michael@0 | 416 | } |
michael@0 | 417 | |
michael@0 | 418 | /** |
michael@0 | 419 | * Enable or disable the bfcache. |
michael@0 | 420 | * |
michael@0 | 421 | * Parameters: |
michael@0 | 422 | * |
michael@0 | 423 | * enable: if true, set max_total_viewers to -1 (the default); if false, set |
michael@0 | 424 | * to 0 (disabled), if a number, set it to that specific number |
michael@0 | 425 | */ |
michael@0 | 426 | function enableBFCache(enable) { |
michael@0 | 427 | var prefs = Components.classes["@mozilla.org/preferences-service;1"] |
michael@0 | 428 | .getService(Components.interfaces.nsIPrefBranch); |
michael@0 | 429 | |
michael@0 | 430 | // If this is the first time the test called enableBFCache(), |
michael@0 | 431 | // store the original value of max_total_viewers, so it can |
michael@0 | 432 | // be restored at the end of the test. |
michael@0 | 433 | if (typeof(gOrigMaxTotalViewers) == "undefined") { |
michael@0 | 434 | gOrigMaxTotalViewers = |
michael@0 | 435 | prefs.getIntPref("browser.sessionhistory.max_total_viewers"); |
michael@0 | 436 | } |
michael@0 | 437 | |
michael@0 | 438 | if (typeof(enable) == "boolean") { |
michael@0 | 439 | if (enable) |
michael@0 | 440 | prefs.setIntPref("browser.sessionhistory.max_total_viewers", -1); |
michael@0 | 441 | else |
michael@0 | 442 | prefs.setIntPref("browser.sessionhistory.max_total_viewers", 0); |
michael@0 | 443 | } |
michael@0 | 444 | else if (typeof(enable) == "number") { |
michael@0 | 445 | prefs.setIntPref("browser.sessionhistory.max_total_viewers", enable); |
michael@0 | 446 | } |
michael@0 | 447 | } |
michael@0 | 448 | |
michael@0 | 449 | /* |
michael@0 | 450 | * get http root for local tests. Use a single extractJarToTmp instead of |
michael@0 | 451 | * extracting for each test. |
michael@0 | 452 | * Returns a file://path if we have a .jar file |
michael@0 | 453 | */ |
michael@0 | 454 | function getHttpRoot() { |
michael@0 | 455 | var location = window.location.href; |
michael@0 | 456 | location = getRootDirectory(location); |
michael@0 | 457 | var jar = getJar(location); |
michael@0 | 458 | if (jar != null) { |
michael@0 | 459 | if (gExtractedPath == null) { |
michael@0 | 460 | var resolved = extractJarToTmp(jar); |
michael@0 | 461 | gExtractedPath = resolved.path; |
michael@0 | 462 | } |
michael@0 | 463 | } else { |
michael@0 | 464 | return null; |
michael@0 | 465 | } |
michael@0 | 466 | return "file://" + gExtractedPath + '/'; |
michael@0 | 467 | } |
michael@0 | 468 | |
michael@0 | 469 | /** |
michael@0 | 470 | * Returns the full HTTP url for a file in the mochitest docshell test |
michael@0 | 471 | * directory. |
michael@0 | 472 | */ |
michael@0 | 473 | function getHttpUrl(filename) { |
michael@0 | 474 | var root = getHttpRoot(); |
michael@0 | 475 | if (root == null) { |
michael@0 | 476 | root = "http://mochi.test:8888/chrome/docshell/test/chrome/"; |
michael@0 | 477 | } |
michael@0 | 478 | return root + filename; |
michael@0 | 479 | } |
michael@0 | 480 | |
michael@0 | 481 | /** |
michael@0 | 482 | * A convenience object with methods that return the current test window, |
michael@0 | 483 | * browser, and document. |
michael@0 | 484 | */ |
michael@0 | 485 | var TestWindow = {}; |
michael@0 | 486 | TestWindow.getWindow = function () { |
michael@0 | 487 | return document.getElementById("content").contentWindow; |
michael@0 | 488 | } |
michael@0 | 489 | TestWindow.getBrowser = function () { |
michael@0 | 490 | return document.getElementById("content"); |
michael@0 | 491 | } |
michael@0 | 492 | TestWindow.getDocument = function () { |
michael@0 | 493 | return document.getElementById("content").contentDocument; |
michael@0 | 494 | } |