summaryrefslogtreecommitdiffstats
path: root/browser/base/content/test/performance/browser_appmenu.js
blob: 3d554d8881c42df7e1c9ae30c3f5b077910123d1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
"use strict";
/* global PanelUI */

const { CustomizableUITestUtils } = ChromeUtils.importESModule(
  "resource://testing-common/CustomizableUITestUtils.sys.mjs"
);
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.sys.mjs",
    ],
  },

  {
    stack: [
      "_calculateMaxHeight@resource:///modules/PanelMultiView.sys.mjs",
      "handleEvent@resource:///modules/PanelMultiView.sys.mjs",
    ],

    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 => {
      // We expect the menu button to get into the active state.
      //
      // XXX For some reason the menu panel isn't in our screenshots, but
      // that's where we actually expect many changes.
      return rects.filter(r => !rectInBoundingClientRect(r, menuButtonRect));
    },
    exceptions: [
      {
        name: "the urlbar placeholder moves up and down by a few pixels",
        condition: r => rectInBoundingClientRect(r, textBoxRect),
      },
      {
        name: "bug 1547341 - a first tab gets drawn early",
        condition: r => rectInBoundingClientRect(r, firstTabRect),
      },
    ],
  };

  // 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 }
  );
});