зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1358719 - Add window resize reflow test. r=florian
MozReview-Commit-ID: 57mLswnXhC8 --HG-- extra : rebase_source : 136833da5984e9b2e5d150a497aad1d7eb632f5d
This commit is contained in:
Родитель
a2c22e61fc
Коммит
62afea2749
|
@ -30,6 +30,7 @@ run-if = debug || devedition || nightly_build # Requires startupRecorder.js, whi
|
||||||
skip-if = (os == 'linux') || (os == 'win' && debug) # Disabled on Linux and Windows debug due to perma failures. Bug 1392320.
|
skip-if = (os == 'linux') || (os == 'win' && debug) # Disabled on Linux and Windows debug due to perma failures. Bug 1392320.
|
||||||
[browser_urlbar_search_reflows.js]
|
[browser_urlbar_search_reflows.js]
|
||||||
skip-if = (debug || ccov) && (os == 'linux' || os == 'win') # Disabled on Linux and Windows debug and ccov due to intermittent timeouts. Bug 1414126, bug 1426611.
|
skip-if = (debug || ccov) && (os == 'linux' || os == 'win') # Disabled on Linux and Windows debug and ccov due to intermittent timeouts. Bug 1414126, bug 1426611.
|
||||||
|
[browser_window_resize_reflows.js]
|
||||||
[browser_windowclose_reflows.js]
|
[browser_windowclose_reflows.js]
|
||||||
[browser_windowopen_flicker.js]
|
[browser_windowopen_flicker.js]
|
||||||
skip-if = (debug && os == 'win') # Disabled on windows debug for intermittent leaks
|
skip-if = (debug && os == 'win') # Disabled on windows debug for intermittent leaks
|
||||||
|
|
|
@ -0,0 +1,138 @@
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
const EXPECTED_REFLOWS = [
|
||||||
|
{
|
||||||
|
stack: [
|
||||||
|
"onOverflow@resource:///modules/CustomizableUI.jsm",
|
||||||
|
],
|
||||||
|
maxCount: 48,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
stack: [
|
||||||
|
"_moveItemsBackToTheirOrigin@resource:///modules/CustomizableUI.jsm",
|
||||||
|
"_onLazyResize@resource:///modules/CustomizableUI.jsm",
|
||||||
|
],
|
||||||
|
maxCount: 5,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
stack: [
|
||||||
|
"_onLazyResize@resource:///modules/CustomizableUI.jsm",
|
||||||
|
],
|
||||||
|
maxCount: 4,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const gToolbar = document.getElementById("PersonalToolbar");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the visibility state on the Bookmarks Toolbar, and
|
||||||
|
* waits for it to transition to fully visible.
|
||||||
|
*
|
||||||
|
* @param visible (bool)
|
||||||
|
* Whether or not the bookmarks toolbar should be made visible.
|
||||||
|
* @returns Promise
|
||||||
|
*/
|
||||||
|
async function toggleBookmarksToolbar(visible) {
|
||||||
|
let transitionPromise =
|
||||||
|
BrowserTestUtils.waitForEvent(gToolbar, "transitionend",
|
||||||
|
e => e.propertyName == "max-height");
|
||||||
|
|
||||||
|
setToolbarVisibility(gToolbar, visible);
|
||||||
|
await transitionPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resizes a browser window to a particular width and height, and
|
||||||
|
* waits for it to reach a "steady state" with respect to its overflowing
|
||||||
|
* toolbars.
|
||||||
|
* @param win (browser window)
|
||||||
|
* The window to resize.
|
||||||
|
* @param width (int)
|
||||||
|
* The width to resize the window to.
|
||||||
|
* @param height (int)
|
||||||
|
* The height to resize the window to.
|
||||||
|
* @returns Promise
|
||||||
|
*/
|
||||||
|
async function resizeWindow(win, width, height) {
|
||||||
|
let toolbarEvent =
|
||||||
|
BrowserTestUtils.waitForEvent(win, "BookmarksToolbarVisibilityUpdated");
|
||||||
|
let resizeEvent =
|
||||||
|
BrowserTestUtils.waitForEvent(win, "resize");
|
||||||
|
let dwu = win.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||||
|
.getInterface(Ci.nsIDOMWindowUtils);
|
||||||
|
dwu.ensureDirtyRootFrame();
|
||||||
|
win.resizeTo(width, height);
|
||||||
|
await resizeEvent;
|
||||||
|
forceImmediateToolbarOverflowHandling(win);
|
||||||
|
await toolbarEvent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This test ensures that there are no unexpected
|
||||||
|
* uninterruptible reflows when resizing windows.
|
||||||
|
*/
|
||||||
|
add_task(async function() {
|
||||||
|
const BOOKMARKS_COUNT = 150;
|
||||||
|
const STARTING_WIDTH = 600;
|
||||||
|
const STARTING_HEIGHT = 400;
|
||||||
|
const SMALL_WIDTH = 150;
|
||||||
|
const SMALL_HEIGHT = 150;
|
||||||
|
|
||||||
|
await PlacesUtils.bookmarks.eraseEverything();
|
||||||
|
|
||||||
|
// Add a bunch of bookmarks to display in the Bookmarks toolbar
|
||||||
|
await PlacesUtils.bookmarks.insertTree({
|
||||||
|
guid: PlacesUtils.bookmarks.toolbarGuid,
|
||||||
|
children: Array(BOOKMARKS_COUNT).fill("")
|
||||||
|
.map((_, i) => ({ url: `http://test.places.${i}/`}))
|
||||||
|
});
|
||||||
|
|
||||||
|
let wasCollapsed = gToolbar.collapsed;
|
||||||
|
Assert.ok(wasCollapsed, "The toolbar is collapsed by default");
|
||||||
|
if (wasCollapsed) {
|
||||||
|
let promiseReady =
|
||||||
|
BrowserTestUtils.waitForEvent(gToolbar, "BookmarksToolbarVisibilityUpdated");
|
||||||
|
await toggleBookmarksToolbar(true);
|
||||||
|
await promiseReady;
|
||||||
|
}
|
||||||
|
|
||||||
|
registerCleanupFunction(async () => {
|
||||||
|
if (wasCollapsed) {
|
||||||
|
await toggleBookmarksToolbar(false);
|
||||||
|
}
|
||||||
|
await PlacesUtils.bookmarks.eraseEverything();
|
||||||
|
await PlacesUtils.history.clear();
|
||||||
|
});
|
||||||
|
|
||||||
|
let win = await prepareSettledWindow();
|
||||||
|
|
||||||
|
if (win.screen.availWidth < STARTING_WIDTH ||
|
||||||
|
win.screen.availHeight < STARTING_HEIGHT) {
|
||||||
|
Assert.ok(false, "This test is running on too small a display - " +
|
||||||
|
`(${STARTING_WIDTH}x${STARTING_HEIGHT} min)`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await resizeWindow(win, STARTING_WIDTH, STARTING_HEIGHT);
|
||||||
|
|
||||||
|
await withReflowObserver(async function() {
|
||||||
|
await resizeWindow(win, SMALL_WIDTH, SMALL_HEIGHT);
|
||||||
|
await resizeWindow(win, STARTING_WIDTH, STARTING_HEIGHT);
|
||||||
|
}, EXPECTED_REFLOWS, win);
|
||||||
|
|
||||||
|
await BrowserTestUtils.closeWindow(win);
|
||||||
|
});
|
|
@ -199,18 +199,33 @@ async function ensureNoPreloadedBrowser(win = window) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The navigation toolbar is overflowable, meaning that some items
|
||||||
|
* will be moved and held within a sub-panel if the window gets too
|
||||||
|
* small to show their icons. The calculation for hiding those items
|
||||||
|
* occurs after resize events, and is debounced using a DeferredTask.
|
||||||
|
* This utility function allows us to fast-forward to just running
|
||||||
|
* that function for that DeferredTask instead of waiting for the
|
||||||
|
* debounce timeout to occur.
|
||||||
|
*/
|
||||||
|
function forceImmediateToolbarOverflowHandling(win) {
|
||||||
|
let overflowableToolbar = win.document.getElementById("nav-bar").overflowable;
|
||||||
|
if (overflowableToolbar._lazyResizeHandler && overflowableToolbar._lazyResizeHandler.isArmed) {
|
||||||
|
overflowableToolbar._lazyResizeHandler.disarm();
|
||||||
|
// Ensure the root frame is dirty before resize so that, if we're
|
||||||
|
// in the middle of a reflow test, we record the reflows deterministically.
|
||||||
|
let dwu = win.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||||
|
.getInterface(Ci.nsIDOMWindowUtils);
|
||||||
|
dwu.ensureDirtyRootFrame();
|
||||||
|
overflowableToolbar._onLazyResize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function prepareSettledWindow() {
|
async function prepareSettledWindow() {
|
||||||
let win = await BrowserTestUtils.openNewBrowserWindow();
|
let win = await BrowserTestUtils.openNewBrowserWindow();
|
||||||
|
|
||||||
await ensureNoPreloadedBrowser(win);
|
await ensureNoPreloadedBrowser(win);
|
||||||
|
forceImmediateToolbarOverflowHandling(win);
|
||||||
let overflowableToolbar = win.document.getElementById("nav-bar").overflowable;
|
|
||||||
if (overflowableToolbar._lazyResizeHandler && overflowableToolbar._lazyResizeHandler.isArmed) {
|
|
||||||
info("forcing deferred overflow handling of the navigation toolbar to happen immediately");
|
|
||||||
overflowableToolbar._lazyResizeHandler.disarm();
|
|
||||||
overflowableToolbar._onLazyResize();
|
|
||||||
}
|
|
||||||
|
|
||||||
return win;
|
return win;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче