summaryrefslogtreecommitdiffstats
path: root/browser/base/content/test/performance/browser_window_resize.js
blob: 0838ae9f8f46c6b83cd0d4c6aac47543e8730f1b (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
130
131
132
/* 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.
 * Instead of adding 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_REFLOWS = [
  /**
   * Nothing here! Please don't add anything new!
   */
];

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");
  win.windowUtils.ensureDirtyRootFrame();
  win.resizeTo(width, height);
  await resizeEvent;
  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("")
      // eslint-disable-next-line @microsoft/sdl/no-insecure-url
      .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 withPerfObserver(
    async function () {
      await resizeWindow(win, SMALL_WIDTH, SMALL_HEIGHT);
      await resizeWindow(win, STARTING_WIDTH, STARTING_HEIGHT);
    },
    { expectedReflows: EXPECTED_REFLOWS, frames: { filter: () => [] } },
    win
  );

  await BrowserTestUtils.closeWindow(win);
});