browser_tabswitch.js (4445B)
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 /* 21 * This test ensures that there are no unexpected 22 * uninterruptible reflows when switching between two 23 * tabs that are both fully visible. 24 */ 25 add_task(async function () { 26 // TODO (bug 1702653): Disable tab shadows for tests since the shadow 27 // can extend outside of the boundingClientRect. The tabRect will need 28 // to grow to include the shadow size. 29 gBrowser.tabContainer.setAttribute("noshadowfortests", "true"); 30 31 await ensureNoPreloadedBrowser(); 32 await disableFxaBadge(); 33 34 // The test starts on about:blank and opens an about:blank 35 // tab which triggers opening the toolbar since 36 // ensureNoPreloadedBrowser sets AboutNewTab.newTabURL to about:blank. 37 await SpecialPowers.pushPrefEnv({ 38 set: [["browser.toolbars.bookmarks.visibility", "never"]], 39 }); 40 41 // At the time of writing, there are no reflows on simple tab switching. 42 // Mochitest will fail if we have no assertions, so we add one here 43 // to make sure nobody adds any new ones. 44 Assert.equal( 45 EXPECTED_REFLOWS.length, 46 0, 47 "We shouldn't have added any new expected reflows." 48 ); 49 50 let origTab = gBrowser.selectedTab; 51 let firstSwitchDone = BrowserTestUtils.waitForEvent(window, "TabSwitchDone"); 52 let otherTab = await BrowserTestUtils.openNewForegroundTab(gBrowser); 53 await firstSwitchDone; 54 55 let tabStripRect = 56 gBrowser.tabContainer.arrowScrollbox.getBoundingClientRect(); 57 let firstTabRect = origTab.getBoundingClientRect(); 58 let tabPaddingStart = parseFloat( 59 getComputedStyle(gBrowser.selectedTab).paddingInlineStart 60 ); 61 let minTabWidth = firstTabRect.width - 2 * tabPaddingStart; 62 if (AppConstants.platform == "macosx") { 63 // On macOS, after bug 1886729, gecko screenshots like the ones for this 64 // test can't screenshot the native titlebar. That, plus the fact that 65 // there's no border or shadow (see bug 1702653) means that we only end up 66 // with the tab text color changing, which is smaller than the tab 67 // background size. 68 minTabWidth = 0; 69 } 70 let maxTabWidth = firstTabRect.width; 71 let inRange = (val, min, max) => min <= val && val <= max; 72 73 await withPerfObserver( 74 async function () { 75 let switchDone = BrowserTestUtils.waitForEvent(window, "TabSwitchDone"); 76 gBrowser.selectedTab = origTab; 77 await switchDone; 78 }, 79 { 80 expectedReflows: EXPECTED_REFLOWS, 81 frames: { 82 filter: rects => 83 rects.filter( 84 r => 85 !( 86 // We expect all changes to be within the tab strip. 87 ( 88 r.y1 >= tabStripRect.top && 89 r.y2 <= tabStripRect.bottom && 90 r.x1 >= tabStripRect.left && 91 r.x2 <= tabStripRect.right && 92 // The tab selection changes between 2 adjacent tabs, so we expect 93 // both to change color at once: this should be a single rect of the 94 // width of 2 tabs. 95 inRange(r.w, minTabWidth, maxTabWidth * 2) 96 ) 97 ) 98 ), 99 exceptions: [ 100 { 101 name: 102 "bug 1446454 - the border between tabs should be painted at" + 103 " the same time as the tab switch", 104 condition: r => 105 // In tab strip 106 r.y1 >= tabStripRect.top && 107 r.y2 <= tabStripRect.bottom && 108 // 1px border, 1px before the end of the first tab. 109 r.w == 1 && 110 r.x1 == firstTabRect.right - 1, 111 }, 112 { 113 name: "bug 1446449 - spurious tab switch spinner", 114 condition: r => 115 AppConstants.DEBUG && 116 // In the content area 117 r.y1 >= 118 document 119 .getElementById("tabbrowser-tabbox") 120 .getBoundingClientRect().top, 121 }, 122 ], 123 }, 124 } 125 ); 126 127 BrowserTestUtils.removeTab(otherTab); 128 });