"use strict"; /* global PanelUI */ const { CustomizableUITestUtils } = ChromeUtils.import( "resource://testing-common/CustomizableUITestUtils.jsm" ); let gCUITestUtils = new CustomizableUITestUtils(window); /** * WHOA THERE: We should never be adding new things to * EXPECTED_APPMENU_OPEN_REFLOWS. This list should slowly go * away as we improve the performance of the front-end. Instead of adding more * reflows to the list, you should be modifying your code to avoid the reflow. * * See https://firefox-source-docs.mozilla.org/performance/bestpractices.html * for tips on how to do that. */ const EXPECTED_APPMENU_OPEN_REFLOWS = [ { stack: [ "openPopup/this._openPopupPromise<@resource:///modules/PanelMultiView.jsm", ], }, { stack: [ "_calculateMaxHeight@resource:///modules/PanelMultiView.jsm", "handleEvent@resource:///modules/PanelMultiView.jsm", ], maxCount: 7, // This number should only ever go down - never up. }, ]; add_task(async function() { await ensureNoPreloadedBrowser(); await disableFxaBadge(); let textBoxRect = gURLBar .querySelector("moz-input-box") .getBoundingClientRect(); let menuButtonRect = document .getElementById("PanelUI-menu-button") .getBoundingClientRect(); let firstTabRect = gBrowser.selectedTab.getBoundingClientRect(); let frameExpectations = { filter: rects => rects.filter( r => !( // We expect the menu button to get into the active state. ( r.y1 >= menuButtonRect.top && r.y2 <= menuButtonRect.bottom && r.x1 >= menuButtonRect.left && r.x2 <= menuButtonRect.right ) ) // XXX For some reason the menu panel isn't in our screenshots, // but that's where we actually expect many changes. ), exceptions: [ { name: "the urlbar placeholder moves up and down by a few pixels", condition: r => r.x1 >= textBoxRect.left && r.x2 <= textBoxRect.right && r.y1 >= textBoxRect.top && r.y2 <= textBoxRect.bottom, }, { name: "bug 1547341 - a first tab gets drawn early", condition: r => r.x1 >= firstTabRect.left && r.x2 <= firstTabRect.right && r.y1 >= firstTabRect.top && r.y2 <= firstTabRect.bottom, }, ], }; // First, open the appmenu. await withPerfObserver(() => gCUITestUtils.openMainMenu(), { expectedReflows: EXPECTED_APPMENU_OPEN_REFLOWS, frames: frameExpectations, }); // Now open a series of subviews, and then close the appmenu. We // should not reflow during any of this. await withPerfObserver( async function() { // This recursive function will take the current main or subview, // find all of the buttons that navigate to subviews inside it, // and click each one individually. Upon entering the new view, // we recurse. When the subviews within a view have been // exhausted, we go back up a level. async function openSubViewsRecursively(currentView) { let navButtons = Array.from( // Ensure that only enabled buttons are tested currentView.querySelectorAll(".subviewbutton-nav:not([disabled])") ); if (!navButtons) { return; } for (let button of navButtons) { info("Click " + button.id); let promiseViewShown = BrowserTestUtils.waitForEvent( PanelUI.panel, "ViewShown" ); button.click(); let viewShownEvent = await promiseViewShown; // Workaround until bug 1363756 is fixed, then this can be removed. let container = PanelUI.multiView.querySelector( ".panel-viewcontainer" ); await TestUtils.waitForCondition(() => { return !container.hasAttribute("width"); }); info("Shown " + viewShownEvent.originalTarget.id); await openSubViewsRecursively(viewShownEvent.originalTarget); promiseViewShown = BrowserTestUtils.waitForEvent( currentView, "ViewShown" ); PanelUI.multiView.goBack(); await promiseViewShown; // Workaround until bug 1363756 is fixed, then this can be removed. await TestUtils.waitForCondition(() => { return !container.hasAttribute("width"); }); } } await openSubViewsRecursively(PanelUI.mainView); await gCUITestUtils.hideMainMenu(); }, { expectedReflows: [], frames: frameExpectations } ); });