browser/base/content/test/general/head.js

Thu, 15 Jan 2015 15:55:04 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 15:55:04 +0100
branch
TOR_BUG_9701
changeset 9
a63d609f5ebe
permissions
-rw-r--r--

Back out 97036ab72558 which inappropriately compared turds to third parties.

     1 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
     3 XPCOMUtils.defineLazyModuleGetter(this, "Promise",
     4   "resource://gre/modules/Promise.jsm");
     5 XPCOMUtils.defineLazyModuleGetter(this, "Task",
     6   "resource://gre/modules/Task.jsm");
     7 XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
     8   "resource://gre/modules/PlacesUtils.jsm");
    10 function whenDelayedStartupFinished(aWindow, aCallback) {
    11   Services.obs.addObserver(function observer(aSubject, aTopic) {
    12     if (aWindow == aSubject) {
    13       Services.obs.removeObserver(observer, aTopic);
    14       executeSoon(aCallback);
    15     }
    16   }, "browser-delayed-startup-finished", false);
    17 }
    19 function findChromeWindowByURI(aURI) {
    20   let windows = Services.wm.getEnumerator(null);
    21   while (windows.hasMoreElements()) {
    22     let win = windows.getNext();
    23     if (win.location.href == aURI)
    24       return win;
    25   }
    26   return null;
    27 }
    29 function updateTabContextMenu(tab) {
    30   let menu = document.getElementById("tabContextMenu");
    31   if (!tab)
    32     tab = gBrowser.selectedTab;
    33   var evt = new Event("");
    34   tab.dispatchEvent(evt);
    35   menu.openPopup(tab, "end_after", 0, 0, true, false, evt);
    36   is(TabContextMenu.contextTab, tab, "TabContextMenu context is the expected tab");
    37   menu.hidePopup();
    38 }
    40 function openToolbarCustomizationUI(aCallback, aBrowserWin) {
    41   if (!aBrowserWin)
    42     aBrowserWin = window;
    44   aBrowserWin.gCustomizeMode.enter();
    46   aBrowserWin.gNavToolbox.addEventListener("customizationready", function UI_loaded() {
    47     aBrowserWin.gNavToolbox.removeEventListener("customizationready", UI_loaded);
    48     executeSoon(function() {
    49       aCallback(aBrowserWin)
    50     });
    51   });
    52 }
    54 function closeToolbarCustomizationUI(aCallback, aBrowserWin) {
    55   aBrowserWin.gNavToolbox.addEventListener("aftercustomization", function unloaded() {
    56     aBrowserWin.gNavToolbox.removeEventListener("aftercustomization", unloaded);
    57     executeSoon(aCallback);
    58   });
    60   aBrowserWin.gCustomizeMode.exit();
    61 }
    63 function waitForCondition(condition, nextTest, errorMsg) {
    64   var tries = 0;
    65   var interval = setInterval(function() {
    66     if (tries >= 30) {
    67       ok(false, errorMsg);
    68       moveOn();
    69     }
    70     var conditionPassed;
    71     try {
    72       conditionPassed = condition();
    73     } catch (e) {
    74       ok(false, e + "\n" + e.stack);
    75       conditionPassed = false;
    76     }
    77     if (conditionPassed) {
    78       moveOn();
    79     }
    80     tries++;
    81   }, 100);
    82   var moveOn = function() { clearInterval(interval); nextTest(); };
    83 }
    85 function getTestPlugin(aName) {
    86   var pluginName = aName || "Test Plug-in";
    87   var ph = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
    88   var tags = ph.getPluginTags();
    90   // Find the test plugin
    91   for (var i = 0; i < tags.length; i++) {
    92     if (tags[i].name == pluginName)
    93       return tags[i];
    94   }
    95   ok(false, "Unable to find plugin");
    96   return null;
    97 }
    99 // call this to set the test plugin(s) initially expected enabled state.
   100 // it will automatically be reset to it's previous value after the test
   101 // ends
   102 function setTestPluginEnabledState(newEnabledState, pluginName) {
   103   var plugin = getTestPlugin(pluginName);
   104   var oldEnabledState = plugin.enabledState;
   105   plugin.enabledState = newEnabledState;
   106   SimpleTest.registerCleanupFunction(function() {
   107     getTestPlugin(pluginName).enabledState = oldEnabledState;
   108   });
   109 }
   111 // after a test is done using the plugin doorhanger, we should just clear
   112 // any permissions that may have crept in
   113 function clearAllPluginPermissions() {
   114   let perms = Services.perms.enumerator;
   115   while (perms.hasMoreElements()) {
   116     let perm = perms.getNext();
   117     if (perm.type.startsWith('plugin')) {
   118       Services.perms.remove(perm.host, perm.type);
   119     }
   120   }
   121 }
   123 function updateBlocklist(aCallback) {
   124   var blocklistNotifier = Cc["@mozilla.org/extensions/blocklist;1"]
   125                           .getService(Ci.nsITimerCallback);
   126   var observer = function() {
   127     Services.obs.removeObserver(observer, "blocklist-updated");
   128     SimpleTest.executeSoon(aCallback);
   129   };
   130   Services.obs.addObserver(observer, "blocklist-updated", false);
   131   blocklistNotifier.notify(null);
   132 }
   134 var _originalTestBlocklistURL = null;
   135 function setAndUpdateBlocklist(aURL, aCallback) {
   136   if (!_originalTestBlocklistURL)
   137     _originalTestBlocklistURL = Services.prefs.getCharPref("extensions.blocklist.url");
   138   Services.prefs.setCharPref("extensions.blocklist.url", aURL);
   139   updateBlocklist(aCallback);
   140 }
   142 function resetBlocklist() {
   143   Services.prefs.setCharPref("extensions.blocklist.url", _originalTestBlocklistURL);
   144 }
   146 function whenNewWindowLoaded(aOptions, aCallback) {
   147   let win = OpenBrowserWindow(aOptions);
   148   win.addEventListener("load", function onLoad() {
   149     win.removeEventListener("load", onLoad, false);
   150     aCallback(win);
   151   }, false);
   152 }
   154 /**
   155  * Waits for all pending async statements on the default connection, before
   156  * proceeding with aCallback.
   157  *
   158  * @param aCallback
   159  *        Function to be called when done.
   160  * @param aScope
   161  *        Scope for the callback.
   162  * @param aArguments
   163  *        Arguments array for the callback.
   164  *
   165  * @note The result is achieved by asynchronously executing a query requiring
   166  *       a write lock.  Since all statements on the same connection are
   167  *       serialized, the end of this write operation means that all writes are
   168  *       complete.  Note that WAL makes so that writers don't block readers, but
   169  *       this is a problem only across different connections.
   170  */
   171 function waitForAsyncUpdates(aCallback, aScope, aArguments) {
   172   let scope = aScope || this;
   173   let args = aArguments || [];
   174   let db = PlacesUtils.history.QueryInterface(Ci.nsPIPlacesDatabase)
   175                               .DBConnection;
   176   let begin = db.createAsyncStatement("BEGIN EXCLUSIVE");
   177   begin.executeAsync();
   178   begin.finalize();
   180   let commit = db.createAsyncStatement("COMMIT");
   181   commit.executeAsync({
   182     handleResult: function() {},
   183     handleError: function() {},
   184     handleCompletion: function(aReason) {
   185       aCallback.apply(scope, args);
   186     }
   187   });
   188   commit.finalize();
   189 }
   191 /**
   192  * Asynchronously check a url is visited.
   194  * @param aURI The URI.
   195  * @param aExpectedValue The expected value.
   196  * @return {Promise}
   197  * @resolves When the check has been added successfully.
   198  * @rejects JavaScript exception.
   199  */
   200 function promiseIsURIVisited(aURI, aExpectedValue) {
   201   let deferred = Promise.defer();
   202   PlacesUtils.asyncHistory.isURIVisited(aURI, function(aURI, aIsVisited) {
   203     deferred.resolve(aIsVisited);
   204   });
   206   return deferred.promise;
   207 }
   209 function whenNewTabLoaded(aWindow, aCallback) {
   210   aWindow.BrowserOpenTab();
   212   let browser = aWindow.gBrowser.selectedBrowser;
   213   if (browser.contentDocument.readyState === "complete") {
   214     aCallback();
   215     return;
   216   }
   218   whenTabLoaded(aWindow.gBrowser.selectedTab, aCallback);
   219 }
   221 function whenTabLoaded(aTab, aCallback) {
   222   let browser = aTab.linkedBrowser;
   223   browser.addEventListener("load", function onLoad() {
   224     browser.removeEventListener("load", onLoad, true);
   225     executeSoon(aCallback);
   226   }, true);
   227 }
   229 function addVisits(aPlaceInfo, aCallback) {
   230   let places = [];
   231   if (aPlaceInfo instanceof Ci.nsIURI) {
   232     places.push({ uri: aPlaceInfo });
   233   } else if (Array.isArray(aPlaceInfo)) {
   234     places = places.concat(aPlaceInfo);
   235   } else {
   236     places.push(aPlaceInfo);
   237    }
   239   // Create mozIVisitInfo for each entry.
   240   let now = Date.now();
   241   for (let i = 0; i < places.length; i++) {
   242     if (!places[i].title) {
   243       places[i].title = "test visit for " + places[i].uri.spec;
   244     }
   245     places[i].visits = [{
   246       transitionType: places[i].transition === undefined ? Ci.nsINavHistoryService.TRANSITION_LINK
   247                                                          : places[i].transition,
   248       visitDate: places[i].visitDate || (now++) * 1000,
   249       referrerURI: places[i].referrer
   250     }];
   251   }
   253   PlacesUtils.asyncHistory.updatePlaces(
   254     places,
   255     {
   256       handleError: function AAV_handleError() {
   257         throw("Unexpected error in adding visit.");
   258       },
   259       handleResult: function () {},
   260       handleCompletion: function UP_handleCompletion() {
   261         if (aCallback)
   262           aCallback();
   263       }
   264     }
   265   );
   266 }
   268 /**
   269  * Ensures that the specified URIs are either cleared or not.
   270  *
   271  * @param aURIs
   272  *        Array of page URIs
   273  * @param aShouldBeCleared
   274  *        True if each visit to the URI should be cleared, false otherwise
   275  */
   276 function promiseHistoryClearedState(aURIs, aShouldBeCleared) {
   277   let deferred = Promise.defer();
   278   let callbackCount = 0;
   279   let niceStr = aShouldBeCleared ? "no longer" : "still";
   280   function callbackDone() {
   281     if (++callbackCount == aURIs.length)
   282       deferred.resolve();
   283   }
   284   aURIs.forEach(function (aURI) {
   285     PlacesUtils.asyncHistory.isURIVisited(aURI, function(aURI, aIsVisited) {
   286       is(aIsVisited, !aShouldBeCleared,
   287          "history visit " + aURI.spec + " should " + niceStr + " exist");
   288       callbackDone();
   289     });
   290   });
   292   return deferred.promise;
   293 }
   295 /**
   296  * Allows waiting for an observer notification once.
   297  *
   298  * @param topic
   299  *        Notification topic to observe.
   300  *
   301  * @return {Promise}
   302  * @resolves The array [subject, data] from the observed notification.
   303  * @rejects Never.
   304  */
   305 function promiseTopicObserved(topic)
   306 {
   307   let deferred = Promise.defer();
   308   Services.obs.addObserver(function PTO_observe(subject, topic, data) {
   309     Services.obs.removeObserver(PTO_observe, topic);
   310     deferred.resolve([subject, data]);
   311   }, topic, false);
   312   return deferred.promise;
   313 }
   315 /**
   316  * Clears history asynchronously.
   317  *
   318  * @return {Promise}
   319  * @resolves When history has been cleared.
   320  * @rejects Never.
   321  */
   322 function promiseClearHistory() {
   323   let promise = promiseTopicObserved(PlacesUtils.TOPIC_EXPIRATION_FINISHED);
   324   PlacesUtils.bhistory.removeAllPages();
   325   return promise;
   326 }
   328 /**
   329  * Waits for the next top-level document load in the current browser.  The URI
   330  * of the document is compared against aExpectedURL.  The load is then stopped
   331  * before it actually starts.
   332  *
   333  * @param aExpectedURL
   334  *        The URL of the document that is expected to load.
   335  * @return promise
   336  */
   337 function waitForDocLoadAndStopIt(aExpectedURL) {
   338   let deferred = Promise.defer();
   339   let progressListener = {
   340     onStateChange: function (webProgress, req, flags, status) {
   341       info("waitForDocLoadAndStopIt: onStateChange: " + req.name);
   342       let docStart = Ci.nsIWebProgressListener.STATE_IS_DOCUMENT |
   343                      Ci.nsIWebProgressListener.STATE_START;
   344       if ((flags & docStart) && webProgress.isTopLevel) {
   345         info("waitForDocLoadAndStopIt: Document start: " +
   346              req.QueryInterface(Ci.nsIChannel).URI.spec);
   347         is(req.originalURI.spec, aExpectedURL,
   348            "waitForDocLoadAndStopIt: The expected URL was loaded");
   349         req.cancel(Components.results.NS_ERROR_FAILURE);
   350         gBrowser.removeProgressListener(progressListener);
   351         deferred.resolve();
   352       }
   353     },
   354   };
   355   gBrowser.addProgressListener(progressListener);
   356   info("waitForDocLoadAndStopIt: Waiting for URL: " + aExpectedURL);
   357   return deferred.promise;
   358 }
   360 let FullZoomHelper = {
   362   selectTabAndWaitForLocationChange: function selectTabAndWaitForLocationChange(tab) {
   363     if (!tab)
   364       throw new Error("tab must be given.");
   365     if (gBrowser.selectedTab == tab)
   366       return Promise.resolve();
   367     gBrowser.selectedTab = tab;
   368     return this.waitForLocationChange();
   369   },
   371   removeTabAndWaitForLocationChange: function removeTabAndWaitForLocationChange(tab) {
   372     tab = tab || gBrowser.selectedTab;
   373     let selected = gBrowser.selectedTab == tab;
   374     gBrowser.removeTab(tab);
   375     if (selected)
   376       return this.waitForLocationChange();
   377     return Promise.resolve();
   378   },
   380   waitForLocationChange: function waitForLocationChange() {
   381     let deferred = Promise.defer();
   382     Services.obs.addObserver(function obs(subj, topic, data) {
   383       Services.obs.removeObserver(obs, topic);
   384       deferred.resolve();
   385     }, "browser-fullZoom:location-change", false);
   386     return deferred.promise;
   387   },
   389   load: function load(tab, url) {
   390     let deferred = Promise.defer();
   391     let didLoad = false;
   392     let didZoom = false;
   394     tab.linkedBrowser.addEventListener("load", function (event) {
   395       event.currentTarget.removeEventListener("load", arguments.callee, true);
   396       didLoad = true;
   397       if (didZoom)
   398         deferred.resolve();
   399     }, true);
   401     this.waitForLocationChange().then(function () {
   402       didZoom = true;
   403       if (didLoad)
   404         deferred.resolve();
   405     });
   407     tab.linkedBrowser.loadURI(url);
   409     return deferred.promise;
   410   },
   412   zoomTest: function zoomTest(tab, val, msg) {
   413     is(ZoomManager.getZoomForBrowser(tab.linkedBrowser), val, msg);
   414   },
   416   enlarge: function enlarge() {
   417     let deferred = Promise.defer();
   418     FullZoom.enlarge(function () deferred.resolve());
   419     return deferred.promise;
   420   },
   422   reduce: function reduce() {
   423     let deferred = Promise.defer();
   424     FullZoom.reduce(function () deferred.resolve());
   425     return deferred.promise;
   426   },
   428   reset: function reset() {
   429     let deferred = Promise.defer();
   430     FullZoom.reset(function () deferred.resolve());
   431     return deferred.promise;
   432   },
   434   BACK: 0,
   435   FORWARD: 1,
   436   navigate: function navigate(direction) {
   437     let deferred = Promise.defer();
   438     let didPs = false;
   439     let didZoom = false;
   441     gBrowser.addEventListener("pageshow", function (event) {
   442       gBrowser.removeEventListener("pageshow", arguments.callee, true);
   443       didPs = true;
   444       if (didZoom)
   445         deferred.resolve();
   446     }, true);
   448     if (direction == this.BACK)
   449       gBrowser.goBack();
   450     else if (direction == this.FORWARD)
   451       gBrowser.goForward();
   453     this.waitForLocationChange().then(function () {
   454       didZoom = true;
   455       if (didPs)
   456         deferred.resolve();
   457     });
   458     return deferred.promise;
   459   },
   461   failAndContinue: function failAndContinue(func) {
   462     return function (err) {
   463       ok(false, err);
   464       func();
   465     };
   466   },
   467 };

mercurial