Bug 1391293 - Remove some hundreds reflows and adapt reflow tests to the new insert method. r=florian draft
authorMarco Bonardo <mbonardo@mozilla.com>
Mon, 18 Sep 2017 11:58:11 +0200
changeset 666905 1b0d5f88f911097c67572060ec6d77fdf4ab1ea4
parent 666904 ca3dd8305d99cba914d28377570c5e933009e9d3
child 732230 63a7285c42af81b8d22b76a0e1f61ce6705137a2
push id80543
push usermak77@bonardo.net
push dateTue, 19 Sep 2017 11:38:28 +0000
reviewersflorian
bugs1391293
milestone57.0a1
Bug 1391293 - Remove some hundreds reflows and adapt reflow tests to the new insert method. r=florian MozReview-Commit-ID: 1a25ZHo2L8n
browser/base/content/test/performance/browser_urlbar_keyed_search_reflows.js
browser/base/content/test/performance/browser_urlbar_search_reflows.js
browser/base/content/test/performance/head.js
toolkit/content/widgets/autocomplete.xml
--- a/browser/base/content/test/performance/browser_urlbar_keyed_search_reflows.js
+++ b/browser/base/content/test/performance/browser_urlbar_keyed_search_reflows.js
@@ -14,16 +14,29 @@ requestLongerTimeout(5);
  * for tips on how to do that.
  */
 
 /* These reflows happen only the first time the awesomebar panel opens. */
 const EXPECTED_REFLOWS_FIRST_OPEN = [
   // Bug 1357054
   {
     stack: [
+      "_handleOverflow@chrome://global/content/bindings/autocomplete.xml",
+      "handleOverUnderflow@chrome://global/content/bindings/autocomplete.xml",
+      "_onChanged@chrome://global/content/bindings/autocomplete.xml",
+      "_appendCurrentResult/<@chrome://global/content/bindings/autocomplete.xml",
+      "setTimeout handler*_appendCurrentResult@chrome://global/content/bindings/autocomplete.xml",
+      "_invalidate@chrome://global/content/bindings/autocomplete.xml",
+      "invalidate@chrome://global/content/bindings/autocomplete.xml"
+    ],
+    times: 18, // This number should only ever go down - never up.
+  },
+
+  {
+    stack: [
       "_rebuild@chrome://browser/content/search/search.xml",
       "set_popup@chrome://browser/content/search/search.xml",
       "enableOneOffSearches@chrome://browser/content/urlbarBindings.xml",
       "_enableOrDisableOneOffSearches@chrome://browser/content/urlbarBindings.xml",
       "urlbar_XBL_Constructor/<@chrome://browser/content/urlbarBindings.xml",
       "openPopup@chrome://global/content/bindings/popup.xml",
       "_openAutocompletePopup@chrome://browser/content/urlbarBindings.xml",
       "openAutocompletePopup@chrome://browser/content/urlbarBindings.xml",
@@ -49,40 +62,32 @@ const EXPECTED_REFLOWS_FIRST_OPEN = [
     ],
     times: 6, // This number should only ever go down - never up.
   },
 
   {
     stack: [
       "adjustHeight@chrome://global/content/bindings/autocomplete.xml",
       "_invalidate/this._adjustHeightTimeout<@chrome://global/content/bindings/autocomplete.xml",
+      "setTimeout handler*_invalidate@chrome://global/content/bindings/autocomplete.xml",
+      "invalidate@chrome://global/content/bindings/autocomplete.xml",
     ],
-    times: 36, // This number should only ever go down - never up.
+    times: 51, // This number should only ever go down - never up.
   },
 
   {
     stack: [
       "_handleOverflow@chrome://global/content/bindings/autocomplete.xml",
       "handleOverUnderflow@chrome://global/content/bindings/autocomplete.xml",
       "_reuseAcItem@chrome://global/content/bindings/autocomplete.xml",
       "_appendCurrentResult@chrome://global/content/bindings/autocomplete.xml",
       "_invalidate@chrome://global/content/bindings/autocomplete.xml",
       "invalidate@chrome://global/content/bindings/autocomplete.xml"
     ],
-    times: 1344, // This number should only ever go down - never up.
-  },
-
-  {
-    stack: [
-      "_handleOverflow@chrome://global/content/bindings/autocomplete.xml",
-      "handleOverUnderflow@chrome://global/content/bindings/autocomplete.xml",
-      "_onChanged@chrome://global/content/bindings/autocomplete.xml",
-      "_appendCurrentResult/<@chrome://global/content/bindings/autocomplete.xml",
-    ],
-    times: 6,
+    times: 60, // This number should only ever go down - never up.
   },
 
   {
     stack: [
       "_openAutocompletePopup@chrome://browser/content/urlbarBindings.xml",
       "openAutocompletePopup@chrome://browser/content/urlbarBindings.xml",
       "openPopup@chrome://global/content/bindings/autocomplete.xml",
       "set_popupOpen@chrome://global/content/bindings/autocomplete.xml",
--- a/browser/base/content/test/performance/browser_urlbar_search_reflows.js
+++ b/browser/base/content/test/performance/browser_urlbar_search_reflows.js
@@ -14,16 +14,30 @@ requestLongerTimeout(5);
  * for tips on how to do that.
  */
 
 /* These reflows happen only the first time the awesomebar panel opens. */
 const EXPECTED_REFLOWS_FIRST_OPEN = [
   // Bug 1357054
   {
     stack: [
+      "_handleOverflow@chrome://global/content/bindings/autocomplete.xml",
+      "handleOverUnderflow@chrome://global/content/bindings/autocomplete.xml",
+      "_onChanged@chrome://global/content/bindings/autocomplete.xml",
+      "_appendCurrentResult/<@chrome://global/content/bindings/autocomplete.xml",
+      "setTimeout handler*_appendCurrentResult@chrome://global/content/bindings/autocomplete.xml",
+      "_invalidate@chrome://global/content/bindings/autocomplete.xml",
+      "invalidate@chrome://global/content/bindings/autocomplete.xml"
+    ],
+    times: 6, // This number should only ever go down - never up.
+    minTimes: 0, // Sometimes this is not hit.
+  },
+
+  {
+    stack: [
       "_rebuild@chrome://browser/content/search/search.xml",
       "set_popup@chrome://browser/content/search/search.xml",
       "enableOneOffSearches@chrome://browser/content/urlbarBindings.xml",
       "_enableOrDisableOneOffSearches@chrome://browser/content/urlbarBindings.xml",
       "urlbar_XBL_Constructor/<@chrome://browser/content/urlbarBindings.xml",
       "openPopup@chrome://global/content/bindings/popup.xml",
       "_openAutocompletePopup@chrome://browser/content/urlbarBindings.xml",
       "openAutocompletePopup@chrome://browser/content/urlbarBindings.xml",
@@ -62,17 +76,17 @@ const EXPECTED_REFLOWS_FIRST_OPEN = [
     stack: [
       "_handleOverflow@chrome://global/content/bindings/autocomplete.xml",
       "handleOverUnderflow@chrome://global/content/bindings/autocomplete.xml",
       "_reuseAcItem@chrome://global/content/bindings/autocomplete.xml",
       "_appendCurrentResult@chrome://global/content/bindings/autocomplete.xml",
       "_invalidate@chrome://global/content/bindings/autocomplete.xml",
       "invalidate@chrome://global/content/bindings/autocomplete.xml"
     ],
-    times: 330, // This number should only ever go down - never up.
+    times: 60, // This number should only ever go down - never up.
   },
 
   {
     stack: [
       "_openAutocompletePopup@chrome://browser/content/urlbarBindings.xml",
       "openAutocompletePopup@chrome://browser/content/urlbarBindings.xml",
       "openPopup@chrome://global/content/bindings/autocomplete.xml",
       "set_popupOpen@chrome://global/content/bindings/autocomplete.xml",
@@ -105,28 +119,16 @@ const EXPECTED_REFLOWS_SECOND_OPEN = [
   {
     stack: [
       "adjustHeight@chrome://global/content/bindings/autocomplete.xml",
       "_invalidate/this._adjustHeightTimeout<@chrome://global/content/bindings/autocomplete.xml",
     ],
     times: 3, // This number should only ever go down - never up.
   },
 
-  {
-    stack: [
-      "_handleOverflow@chrome://global/content/bindings/autocomplete.xml",
-      "handleOverUnderflow@chrome://global/content/bindings/autocomplete.xml",
-      "_reuseAcItem@chrome://global/content/bindings/autocomplete.xml",
-      "_appendCurrentResult@chrome://global/content/bindings/autocomplete.xml",
-      "_invalidate@chrome://global/content/bindings/autocomplete.xml",
-      "invalidate@chrome://global/content/bindings/autocomplete.xml"
-    ],
-    times: 384, // This number should only ever go down - never up.
-  },
-
   // Bug 1384256
   {
     stack: [
       "_openAutocompletePopup@chrome://browser/content/urlbarBindings.xml",
       "openAutocompletePopup@chrome://browser/content/urlbarBindings.xml",
       "openPopup@chrome://global/content/bindings/autocomplete.xml",
       "set_popupOpen@chrome://global/content/bindings/autocomplete.xml",
     ],
@@ -203,14 +205,16 @@ add_task(async function() {
     // especially if it's GC'ing from previous tests.
     await new Promise(resolve => win.requestIdleCallback(resolve, { timeout: 1000 }));
 
     let hiddenPromise = BrowserTestUtils.waitForEvent(URLBar.popup, "popuphidden");
     EventUtils.synthesizeKey("VK_ESCAPE", {}, win);
     await hiddenPromise;
   };
 
+  info("First opening");
   await withReflowObserver(testFn, EXPECTED_REFLOWS_FIRST_OPEN, win);
 
+  info("Second opening");
   await withReflowObserver(testFn, EXPECTED_REFLOWS_SECOND_OPEN, win);
 
   await BrowserTestUtils.closeWindow(win);
 });
--- a/browser/base/content/test/performance/head.js
+++ b/browser/base/content/test/performance/head.js
@@ -16,39 +16,43 @@ XPCOMUtils.defineLazyModuleGetter(this, 
  *        dirtying outside of the normal mechanism.
  * @param expectedReflows (Array, optional)
  *        An Array of Objects representing reflows.
  *
  *        Example:
  *
  *        [
  *          {
- *            // This reflow is caused by lorem ipsum
+ *            // This reflow is caused by lorem ipsum.
+ *            // Sometimes, due to unpredictable timings, the reflow may be hit
+ *            // less times, or not hit at all; in such a case a minTimes
+ *            // property can be provided to avoid intermittent failures.
  *            stack: [
  *              "select@chrome://global/content/bindings/textbox.xml",
  *              "focusAndSelectUrlBar@chrome://browser/content/browser.js",
  *              "openLinkIn@chrome://browser/content/utilityOverlay.js",
  *              "openUILinkIn@chrome://browser/content/utilityOverlay.js",
  *              "BrowserOpenTab@chrome://browser/content/browser.js",
  *            ],
  *            // We expect this particular reflow to happen 2 times
  *            times: 2,
+ *            // Sometimes this is not hit.
+ *            minTimes: 0
  *          },
  *
  *          {
  *            // This reflow is caused by lorem ipsum. We expect this reflow
  *            // to only happen once, so we can omit the "times" property.
  *            stack: [
  *              "get_scrollPosition@chrome://global/content/bindings/scrollbox.xml",
  *              "_fillTrailingGap@chrome://browser/content/tabbrowser.xml",
  *              "_handleNewTab@chrome://browser/content/tabbrowser.xml",
  *              "onxbltransitionend@chrome://browser/content/tabbrowser.xml",
  *            ],
  *          }
- *
  *        ]
  *
  *        Note that line numbers are not included in the stacks.
  *
  *        Order of the reflows doesn't matter. Expected reflows that aren't seen
  *        will cause an assertion failure. When this argument is not passed,
  *        it defaults to the empty Array, meaning no reflows are expected.
  * @param window (browser window, optional)
@@ -103,16 +107,19 @@ async function withReflowObserver(testFn
         return;
       }
 
       let index = expectedReflows.findIndex(reflow => path.startsWith(reflow.stack.join("|")));
 
       if (index != -1) {
         Assert.ok(true, "expected uninterruptible reflow: '" +
                   JSON.stringify(pathWithLineNumbers, null, "\t") + "'");
+        if (expectedReflows[index].minTimes) {
+          expectedReflows[index].minTimes--;
+        }
         if (--expectedReflows[index].times == 0) {
           expectedReflows.splice(index, 1);
         }
       } else {
         Assert.ok(false, "unexpected uninterruptible reflow \n" +
                          JSON.stringify(pathWithLineNumbers, null, "\t") + "\n");
       }
     },
@@ -134,21 +141,23 @@ async function withReflowObserver(testFn
 
   els.addListenerForAllEvents(win, dirtyFrameFn, true);
 
   try {
     dirtyFrameFn();
     await testFn(dirtyFrameFn);
   } finally {
     for (let remainder of expectedReflows) {
-      Assert.ok(false,
-                `Unused expected reflow: ${JSON.stringify(remainder.stack, null, "\t")}\n` +
-                `This reflow was supposed to be hit ${remainder.times} more time(s).\n` +
-                "This is probably a good thing - just remove it from the " +
-                "expected list.");
+      if (!Number.isInteger(remainder.minTimes) || remainder.minTimes > 0) {
+        Assert.ok(false,
+                  `Unused expected reflow: ${JSON.stringify(remainder.stack, null, "\t")}\n` +
+                  `This reflow was supposed to be hit ${remainder.minTimes || remainder.times} more time(s).\n` +
+                  "This is probably a good thing - just remove it from the " +
+                  "expected list.");
+      }
     }
 
     els.removeListenerForAllEvents(win, dirtyFrameFn, true);
     docShell.removeWeakReflowObserver(observer);
   }
 }
 
 async function ensureNoPreloadedBrowser() {
@@ -236,16 +245,17 @@ async function removeAllButFirstTab() {
   await SpecialPowers.popPrefEnv();
 }
 
 /**
  * Adds some entries to the Places database so that we can
  * do semi-realistic look-ups in the URL bar.
  */
 async function addDummyHistoryEntries() {
+  await PlacesTestUtils.clearHistory();
   const NUM_VISITS = 10;
   let visits = [];
 
   for (let i = 0; i < NUM_VISITS; ++i) {
     visits.push({
       uri: `http://example.com/urlbar-reflows-${i}`,
       title: `Reflow test for URL bar entry #${i}`,
     });
--- a/toolkit/content/widgets/autocomplete.xml
+++ b/toolkit/content/widgets/autocomplete.xml
@@ -2109,17 +2109,22 @@ extends="chrome://global/content/binding
                 action.params.engineName == popup.overrideSearchEngineName) {
 
               this.collapsed = false;
               // Call adjustSiteIconStart only after setting collapsed=
               // false.  The calculations it does may be wrong otherwise.
               this.adjustSiteIconStart(popup._siteIconStart);
               // The popup may have changed size between now and the last
               // time the item was shown, so always handle over/underflow.
-              this.handleOverUnderflow();
+              let dwu = window.getInterface(Ci.nsIDOMWindowUtils);
+              let popupWidth = dwu.getBoundsWithoutFlushing(this.parentNode).width;
+              if (!this._previousPopupWidth || this._previousPopupWidth != popupWidth) {
+                this._previousPopupWidth = popupWidth;
+                this.handleOverUnderflow();
+              }
 
               return true;
             }
 
             return false;
           ]]>
         </body>
       </method>