summaryrefslogtreecommitdiffstats
path: root/browser/base/content/test/performance/browser_windowopen.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/base/content/test/performance/browser_windowopen.js')
-rw-r--r--browser/base/content/test/performance/browser_windowopen.js182
1 files changed, 182 insertions, 0 deletions
diff --git a/browser/base/content/test/performance/browser_windowopen.js b/browser/base/content/test/performance/browser_windowopen.js
new file mode 100644
index 0000000000..ebc924c3c6
--- /dev/null
+++ b/browser/base/content/test/performance/browser_windowopen.js
@@ -0,0 +1,182 @@
+/* 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!
+ */
+];
+
+// We'll assume the changes we are seeing are due to this focus change if
+// there are at least 5 areas that changed near the top of the screen, or if
+// the toolbar background is involved on OSX, but will only ignore this once.
+function isLikelyFocusChange(rects) {
+ if (rects.length > 5 && rects.every(r => r.y2 < 100)) {
+ return true;
+ }
+ if (
+ Services.appinfo.OS == "Darwin" &&
+ rects.length == 2 &&
+ rects.every(r => r.y1 == 0 && r.h == 33)
+ ) {
+ return true;
+ }
+ return false;
+}
+
+/*
+ * This test ensures that there are no unexpected
+ * uninterruptible reflows or flickering areas when opening new windows.
+ */
+add_task(async function () {
+ // Flushing all caches helps to ensure that we get consistent
+ // behaviour when opening a new window, even if windows have been
+ // opened in previous tests.
+ Services.obs.notifyObservers(null, "startupcache-invalidate");
+ Services.obs.notifyObservers(null, "chrome-flush-caches");
+
+ let bookmarksToolbarRect = await getBookmarksToolbarRect();
+
+ let win = window.openDialog(
+ AppConstants.BROWSER_CHROME_URL,
+ "_blank",
+ "chrome,all,dialog=no,remote,suppressanimation",
+ "about:home"
+ );
+
+ await disableFxaBadge();
+
+ let alreadyFocused = false;
+ let inRange = (val, min, max) => min <= val && val <= max;
+ let expectations = {
+ expectedReflows: EXPECTED_REFLOWS,
+ frames: {
+ filter(rects, frame, previousFrame) {
+ // The first screenshot we get in OSX / Windows shows an unfocused browser
+ // window for some reason. See bug 1445161.
+ if (!alreadyFocused && isLikelyFocusChange(rects)) {
+ alreadyFocused = true;
+ todo(
+ false,
+ "bug 1445161 - the window should be focused at first paint, " +
+ rects.toSource()
+ );
+ return [];
+ }
+
+ return rects;
+ },
+ exceptions: [
+ {
+ name: "bug 1421463 - reload toolbar icon shouldn't flicker",
+ condition: r =>
+ inRange(r.h, 13, 14) &&
+ inRange(r.w, 14, 16) && // icon size
+ inRange(r.y1, 40, 80) && // in the toolbar
+ inRange(r.x1, 65, 100), // near the left side of the screen
+ },
+ {
+ name: "bug 1555842 - the urlbar shouldn't flicker",
+ condition: r => {
+ let inputFieldRect = win.gURLBar.inputField.getBoundingClientRect();
+
+ return (
+ (!AppConstants.DEBUG ||
+ (AppConstants.platform == "linux" && AppConstants.ASAN)) &&
+ r.x1 >= inputFieldRect.left &&
+ r.x2 <= inputFieldRect.right &&
+ r.y1 >= inputFieldRect.top &&
+ r.y2 <= inputFieldRect.bottom
+ );
+ },
+ },
+ {
+ name: "Initial bookmark icon appearing after startup",
+ condition: r =>
+ r.w == 16 &&
+ r.h == 16 && // icon size
+ inRange(
+ r.y1,
+ bookmarksToolbarRect.top,
+ bookmarksToolbarRect.top + bookmarksToolbarRect.height / 2
+ ) && // in the toolbar
+ inRange(r.x1, 11, 13), // very close to the left of the screen
+ },
+ {
+ // Note that the length and x values here are a bit weird because on
+ // some fonts, we appear to detect the two words separately.
+ name: "Initial bookmark text ('Getting Started' or 'Get Involved') appearing after startup",
+ condition: r =>
+ inRange(r.w, 25, 120) && // length of text
+ inRange(r.h, 9, 15) && // height of text
+ inRange(
+ r.y1,
+ bookmarksToolbarRect.top,
+ bookmarksToolbarRect.top + bookmarksToolbarRect.height / 2
+ ) && // in the toolbar
+ inRange(r.x1, 30, 90), // close to the left of the screen
+ },
+ ],
+ },
+ };
+
+ await withPerfObserver(
+ async function () {
+ // Avoid showing the remotecontrol UI.
+ await new Promise(resolve => {
+ win.addEventListener(
+ "DOMContentLoaded",
+ () => {
+ delete win.Marionette;
+ win.Marionette = { running: false };
+ resolve();
+ },
+ { once: true }
+ );
+ });
+
+ await TestUtils.topicObserved(
+ "browser-delayed-startup-finished",
+ subject => subject == win
+ );
+
+ let promises = [
+ BrowserTestUtils.firstBrowserLoaded(win, false),
+ BrowserTestUtils.browserStopped(
+ win.gBrowser.selectedBrowser,
+ "about:home"
+ ),
+ ];
+
+ await Promise.all(promises);
+
+ await new Promise(resolve => {
+ // 10 is an arbitrary value here, it needs to be at least 2 to avoid
+ // races with code initializing itself using idle callbacks.
+ (function waitForIdle(count = 10) {
+ if (!count) {
+ resolve();
+ return;
+ }
+ Services.tm.idleDispatchToMainThread(() => {
+ waitForIdle(count - 1);
+ });
+ })();
+ });
+ },
+ expectations,
+ win
+ );
+
+ await BrowserTestUtils.closeWindow(win);
+});