tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

browser_windowopen.js (6746B)


      1 /* Any copyright is dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 /**
      7 * WHOA THERE: We should never be adding new things to EXPECTED_REFLOWS.
      8 * Instead of adding reflows to the list, you should be modifying your code to
      9 * avoid the reflow.
     10 *
     11 * See https://firefox-source-docs.mozilla.org/performance/bestpractices.html
     12 * for tips on how to do that.
     13 */
     14 const EXPECTED_REFLOWS = [
     15  /**
     16   * Nothing here! Please don't add anything new!
     17   */
     18 ];
     19 
     20 add_setup(async function setup() {
     21  SpecialPowers.pushPrefEnv({
     22    set: [["ui.prefersReducedMotion", 1]],
     23  });
     24 });
     25 
     26 const SIDEBAR_REVAMP = Services.prefs.getBoolPref("sidebar.revamp");
     27 
     28 /*
     29 * This test ensures that there are no unexpected
     30 * uninterruptible reflows or flickering areas when opening new windows.
     31 */
     32 add_task(async function () {
     33  // Flushing all caches helps to ensure that we get consistent
     34  // behaviour when opening a new window, even if windows have been
     35  // opened in previous tests.
     36  Services.obs.notifyObservers(null, "startupcache-invalidate");
     37  Services.obs.notifyObservers(null, "chrome-flush-caches");
     38 
     39  let bookmarksToolbarRect = await getBookmarksToolbarRect();
     40 
     41  let win = window.openDialog(
     42    AppConstants.BROWSER_CHROME_URL,
     43    "_blank",
     44    "chrome,all,dialog=no,remote,suppressanimation",
     45    "about:home"
     46  );
     47 
     48  await disableFxaBadge();
     49 
     50  let alreadyFocused = false;
     51  let inRange = (val, min, max) => min <= val && val <= max;
     52  let tabBoundingRect = undefined;
     53  let urlbarBoundingRect = undefined;
     54  let expectations = {
     55    expectedReflows: EXPECTED_REFLOWS,
     56    frames: {
     57      filter(rects, frame) {
     58        // The first screenshot we get in OSX / Windows shows an unfocused browser
     59        // window for some reason. See bug 1445161.
     60        if (!alreadyFocused && isLikelyFocusChange(rects, frame)) {
     61          todo(
     62            false,
     63            "bug 1445161 - the window should be focused at first paint, " +
     64              rects.toSource()
     65          );
     66          return [];
     67        }
     68        alreadyFocused = true;
     69        return rects;
     70      },
     71      exceptions: [
     72        {
     73          name: "bug 1421463 - reload toolbar icon shouldn't flicker",
     74          condition: r => {
     75            // sidebar.revamp places the sidebar button in the toolbar,
     76            // which offsets the position of the reload button by about 36px.
     77            const xOffset = SIDEBAR_REVAMP ? 36 : 0;
     78            return (
     79              inRange(r.h, 13, 14) &&
     80              inRange(r.w, 14, 16) && // icon size
     81              inRange(r.y1, 40, 80) && // in the toolbar
     82              inRange(r.x1, 65 + xOffset, 100 + xOffset) // near the left side of the screen
     83            );
     84          },
     85        },
     86        {
     87          name: "bug 1555842 - the urlbar shouldn't flicker",
     88          condition: r => {
     89            let inputFieldRect = win.gURLBar.inputField.getBoundingClientRect();
     90 
     91            return (
     92              (!AppConstants.DEBUG ||
     93                (AppConstants.platform == "linux" && AppConstants.ASAN)) &&
     94              r.x1 >= inputFieldRect.left &&
     95              r.x2 <= inputFieldRect.right &&
     96              r.y1 >= inputFieldRect.top &&
     97              r.y2 <= inputFieldRect.bottom
     98            );
     99          },
    100        },
    101        {
    102          name: "Pixel snapping on urlbar bottom border on MacOS & Windows",
    103          condition(r) {
    104            if (!urlbarBoundingRect) {
    105              urlbarBoundingRect = document
    106                .getElementById("urlbar")
    107                .getBoundingClientRect();
    108            }
    109            return rectMatchesBottomBorder(r, urlbarBoundingRect);
    110          },
    111        },
    112        {
    113          name: "Initial bookmark icon appearing after startup",
    114          condition: r =>
    115            r.w == 16 &&
    116            r.h == 16 && // icon size
    117            inRange(
    118              r.y1,
    119              bookmarksToolbarRect.top,
    120              bookmarksToolbarRect.top + bookmarksToolbarRect.height / 2
    121            ) && // in the toolbar
    122            inRange(r.x1, 11, 13), // very close to the left of the screen
    123        },
    124        {
    125          // Note that the length and x values here are a bit weird because on
    126          // some fonts, we appear to detect the two words separately.
    127          name: "Initial bookmark text ('Getting Started' or 'Get Involved') appearing after startup",
    128          condition: r =>
    129            inRange(r.w, 25, 120) && // length of text
    130            inRange(r.h, 9, 15) && // height of text
    131            inRange(
    132              r.y1,
    133              bookmarksToolbarRect.top,
    134              bookmarksToolbarRect.top + bookmarksToolbarRect.height / 2
    135            ) && // in the toolbar
    136            inRange(r.x1, 30, 90), // close to the left of the screen
    137        },
    138        {
    139          name: "Shadow around active tab should not flicker on macOS (bug 1960967)",
    140          condition(r) {
    141            const tabRect = tabBoundingRect
    142              ? tabBoundingRect
    143              : (tabBoundingRect = gBrowser.tabContainer
    144                  .querySelector("tab[selected=true] .tab-background")
    145                  .getBoundingClientRect());
    146            return (
    147              inRange(r.x1, tabRect.x - 2, tabRect.x + 2) &&
    148              inRange(r.y1, tabRect.y - 2, tabRect.y + 2) &&
    149              inRange(r.w, tabRect.width - 4, tabRect.width + 4) &&
    150              inRange(r.h, tabRect.height - 4, tabRect.height + 4)
    151            );
    152          },
    153        },
    154      ],
    155    },
    156  };
    157 
    158  await withPerfObserver(
    159    async function () {
    160      // Avoid showing the remotecontrol UI.
    161      await new Promise(resolve => {
    162        win.addEventListener(
    163          "DOMContentLoaded",
    164          () => {
    165            delete win.Marionette;
    166            win.Marionette = { running: false };
    167            resolve();
    168          },
    169          { once: true }
    170        );
    171      });
    172 
    173      await TestUtils.topicObserved(
    174        "browser-delayed-startup-finished",
    175        subject => subject == win
    176      );
    177 
    178      let promises = [
    179        BrowserTestUtils.firstBrowserLoaded(win, false),
    180        BrowserTestUtils.browserStopped(
    181          win.gBrowser.selectedBrowser,
    182          "about:home"
    183        ),
    184      ];
    185 
    186      await Promise.all(promises);
    187 
    188      await new Promise(resolve => {
    189        // 10 is an arbitrary value here, it needs to be at least 2 to avoid
    190        // races with code initializing itself using idle callbacks.
    191        (function waitForIdle(count = 10) {
    192          if (!count) {
    193            resolve();
    194            return;
    195          }
    196          Services.tm.idleDispatchToMainThread(() => {
    197            waitForIdle(count - 1);
    198          });
    199        })();
    200      });
    201    },
    202    expectations,
    203    win
    204  );
    205 
    206  await BrowserTestUtils.closeWindow(win);
    207 });