forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			195 lines
		
	
	
	
		
			7.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			195 lines
		
	
	
	
		
			7.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
"use strict";
 | 
						|
 | 
						|
// There are a _lot_ of reflows in this test, and processing them takes
 | 
						|
// time. On slower builds, we need to boost our allowed test time.
 | 
						|
requestLongerTimeout(5);
 | 
						|
 | 
						|
/**
 | 
						|
 * WHOA THERE: We should never be adding new things to EXPECTED_REFLOWS. This
 | 
						|
 * is a whitelist that should slowly go away as we improve the performance of
 | 
						|
 * the front-end. Instead of adding more reflows to the whitelist, you should
 | 
						|
 * be modifying your code to avoid the reflow.
 | 
						|
 *
 | 
						|
 * See https://developer.mozilla.org/en-US/Firefox/Performance_best_practices_for_Firefox_fe_engineers
 | 
						|
 * for tips on how to do that.
 | 
						|
 */
 | 
						|
 | 
						|
/* These reflows happen only the first time the awesomebar panel opens. */
 | 
						|
const EXPECTED_REFLOWS_FIRST_OPEN = [];
 | 
						|
if (AppConstants.DEBUG ||
 | 
						|
    AppConstants.platform == "linux" ||
 | 
						|
    AppConstants.platform == "macosx" ||
 | 
						|
    AppConstants.isPlatformAndVersionAtLeast("win", "10")) {
 | 
						|
  EXPECTED_REFLOWS_FIRST_OPEN.push({
 | 
						|
    stack: [
 | 
						|
      "_rebuild@chrome://browser/content/search/search.xml",
 | 
						|
      "set_popup@chrome://browser/content/search/search.xml",
 | 
						|
      "set_oneOffSearchesEnabled@chrome://browser/content/urlbarBindings.xml",
 | 
						|
      "_enableOrDisableOneOffSearches@chrome://browser/content/urlbarBindings.xml",
 | 
						|
      "@chrome://browser/content/urlbarBindings.xml",
 | 
						|
      "_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",
 | 
						|
    ],
 | 
						|
  });
 | 
						|
}
 | 
						|
EXPECTED_REFLOWS_FIRST_OPEN.push(
 | 
						|
  {
 | 
						|
    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",
 | 
						|
    ],
 | 
						|
    maxCount: 36, // This number should only ever go down - never up.
 | 
						|
  },
 | 
						|
 | 
						|
  {
 | 
						|
    stack: [
 | 
						|
      "_handleOverflow@chrome://global/content/bindings/autocomplete.xml",
 | 
						|
      "handleOverUnderflow@chrome://global/content/bindings/autocomplete.xml",
 | 
						|
      "_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",
 | 
						|
    ],
 | 
						|
    maxCount: 6, // This number should only ever go down - never up.
 | 
						|
  },
 | 
						|
 | 
						|
  // Bug 1359989
 | 
						|
  {
 | 
						|
    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",
 | 
						|
    ],
 | 
						|
  }
 | 
						|
);
 | 
						|
 | 
						|
/* These reflows happen everytime the awesomebar panel opens. */
 | 
						|
const EXPECTED_REFLOWS_SECOND_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",
 | 
						|
    ],
 | 
						|
    maxCount: 24, // This number should only ever go down - never up.
 | 
						|
  },
 | 
						|
 | 
						|
  // Bug 1359989
 | 
						|
  {
 | 
						|
    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",
 | 
						|
    ],
 | 
						|
  },
 | 
						|
];
 | 
						|
 | 
						|
const SEARCH_TERM = "urlbar-reflows-" + Date.now();
 | 
						|
 | 
						|
add_task(async function setup() {
 | 
						|
  await addDummyHistoryEntries(SEARCH_TERM);
 | 
						|
});
 | 
						|
 | 
						|
/**
 | 
						|
 * This test ensures that there are no unexpected
 | 
						|
 * uninterruptible reflows when typing into the URL bar
 | 
						|
 * with the default values in Places.
 | 
						|
 */
 | 
						|
add_task(async function() {
 | 
						|
  let win = await prepareSettledWindow();
 | 
						|
 | 
						|
  let URLBar = win.gURLBar;
 | 
						|
  let popup = URLBar.popup;
 | 
						|
 | 
						|
  URLBar.focus();
 | 
						|
  URLBar.value = SEARCH_TERM;
 | 
						|
  let testFn = async function() {
 | 
						|
    let oldInvalidate = popup.invalidate.bind(popup);
 | 
						|
    let oldResultsAdded = popup.onResultsAdded.bind(popup);
 | 
						|
    let oldSetTimeout = win.setTimeout;
 | 
						|
 | 
						|
    // We need to invalidate the frame tree outside of the normal
 | 
						|
    // mechanism since invalidations and result additions to the
 | 
						|
    // URL bar occur without firing JS events (which is how we
 | 
						|
    // normally know to dirty the frame tree).
 | 
						|
    popup.invalidate = (reason) => {
 | 
						|
      dirtyFrame(win);
 | 
						|
      oldInvalidate(reason);
 | 
						|
    };
 | 
						|
 | 
						|
    popup.onResultsAdded = () => {
 | 
						|
      dirtyFrame(win);
 | 
						|
      oldResultsAdded();
 | 
						|
    };
 | 
						|
 | 
						|
    win.setTimeout = (fn, ms) => {
 | 
						|
      return oldSetTimeout(() => {
 | 
						|
        dirtyFrame(win);
 | 
						|
        fn();
 | 
						|
      }, ms);
 | 
						|
    };
 | 
						|
 | 
						|
    URLBar.controller.startSearch(URLBar.value);
 | 
						|
    await BrowserTestUtils.waitForEvent(URLBar.popup, "popupshown");
 | 
						|
    await BrowserTestUtils.waitForCondition(() => {
 | 
						|
      return URLBar.controller.searchStatus >=
 | 
						|
        Ci.nsIAutoCompleteController.STATUS_COMPLETE_NO_MATCH;
 | 
						|
    });
 | 
						|
    let matchCount = URLBar.popup.matchCount;
 | 
						|
    await BrowserTestUtils.waitForCondition(() => {
 | 
						|
      return URLBar.popup.richlistbox.children.length == matchCount;
 | 
						|
    });
 | 
						|
 | 
						|
    URLBar.controller.stopSearch();
 | 
						|
    // There are several setTimeout(fn, 0); calls inside autocomplete.xml
 | 
						|
    // that we need to wait for. Since those have higher priority than
 | 
						|
    // idle callbacks, we can be sure they will have run once this
 | 
						|
    // idle callback is called. The timeout seems to be required in
 | 
						|
    // automation - presumably because the machines can be pretty busy
 | 
						|
    // 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;
 | 
						|
  };
 | 
						|
 | 
						|
  let dropmarkerRect = document.getAnonymousElementByAttribute(gURLBar,
 | 
						|
    "anonid", "historydropmarker").getBoundingClientRect();
 | 
						|
  let textBoxRect = document.getAnonymousElementByAttribute(gURLBar,
 | 
						|
    "anonid", "moz-input-box").getBoundingClientRect();
 | 
						|
  let expectedRects = {
 | 
						|
    filter: rects => rects.filter(r => !(
 | 
						|
      // We put text into the urlbar so expect its textbox to change.
 | 
						|
      (r.x1 >= textBoxRect.left && r.x2 <= textBoxRect.right &&
 | 
						|
       r.y1 >= textBoxRect.top && r.y2 <= textBoxRect.bottom) ||
 | 
						|
      // The dropmarker is displayed as active during some of the test.
 | 
						|
      // dropmarkerRect.left isn't always an integer, hence the - 1 and + 1
 | 
						|
      (r.x1 >= dropmarkerRect.left - 1 && r.x2 <= dropmarkerRect.right + 1 &&
 | 
						|
       r.y1 >= dropmarkerRect.top && r.y2 <= dropmarkerRect.bottom)
 | 
						|
      // XXX For some reason the awesomebar panel isn't in our screenshots,
 | 
						|
      // but that's where we actually expect many changes.
 | 
						|
    )),
 | 
						|
  };
 | 
						|
 | 
						|
  info("First opening");
 | 
						|
  await withPerfObserver(testFn, {expectedReflows: EXPECTED_REFLOWS_FIRST_OPEN,
 | 
						|
                                  frames: expectedRects}, win);
 | 
						|
 | 
						|
  info("Second opening");
 | 
						|
  await withPerfObserver(testFn, {expectedReflows: EXPECTED_REFLOWS_SECOND_OPEN,
 | 
						|
                                  frames: expectedRects}, win);
 | 
						|
 | 
						|
  await BrowserTestUtils.closeWindow(win);
 | 
						|
});
 |