browser_title_flicker.js (5579B)
1 const TEST_PATH = 2 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 3 "http://example.com/browser/browser/base/content/test/favicons/"; 4 5 function waitForAttributeChange(tab, attr) { 6 info(`Waiting for attribute ${attr}`); 7 return new Promise(resolve => { 8 let listener = event => { 9 if (event.detail.changed.includes(attr)) { 10 tab.removeEventListener("TabAttrModified", listener); 11 resolve(); 12 } 13 }; 14 15 tab.addEventListener("TabAttrModified", listener); 16 }); 17 } 18 19 function waitForPendingIcon() { 20 return new Promise(resolve => { 21 let listener = () => { 22 LinkHandlerParent.removeListenerForTests(listener); 23 resolve(); 24 }; 25 26 LinkHandlerParent.addListenerForTests(listener); 27 }); 28 } 29 30 add_setup(async function () { 31 await SpecialPowers.pushPrefEnv({ 32 set: [["test.wait300msAfterTabSwitch", true]], 33 }); 34 }); 35 36 // Verify that the title doesn't flicker if the icon takes too long to load. 37 // We expect to see events in the following order: 38 // "label" added to tab 39 // "busy" removed from tab 40 // icon available 41 // In all those cases the title should be in the same position. 42 add_task(async () => { 43 await BrowserTestUtils.withNewTab( 44 { gBrowser, url: "about:blank" }, 45 async browser => { 46 let tab = gBrowser.getTabForBrowser(browser); 47 BrowserTestUtils.startLoadingURIString( 48 browser, 49 TEST_PATH + "file_with_slow_favicon.html" 50 ); 51 52 await waitForAttributeChange(tab, "label"); 53 ok(tab.hasAttribute("busy"), "Should have seen the busy attribute"); 54 let label = tab.textLabel; 55 ok(label.textContent.includes("file_with_slow_favicon.html")); 56 let bounds = label.getBoundingClientRect(); 57 58 await waitForAttributeChange(tab, "busy"); 59 ok( 60 !tab.hasAttribute("busy"), 61 "Should have seen the busy attribute removed" 62 ); 63 let newBounds = label.getBoundingClientRect(); 64 is( 65 bounds.x, 66 newBounds.left, 67 "Should have seen the title in the same place." 68 ); 69 70 await waitForFaviconMessage(true); 71 newBounds = label.getBoundingClientRect(); 72 is( 73 bounds.x, 74 newBounds.left, 75 "Should have seen the title in the same place." 76 ); 77 } 78 ); 79 }); 80 81 // Verify that the title doesn't flicker if a new icon is detected after load. 82 add_task(async () => { 83 let iconAvailable = waitForFaviconMessage(true); 84 await BrowserTestUtils.withNewTab( 85 { gBrowser, url: TEST_PATH + "blank.html" }, 86 async browser => { 87 let icon = await iconAvailable; 88 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 89 is(icon.iconURL, "http://example.com/favicon.ico"); 90 91 let tab = gBrowser.getTabForBrowser(browser); 92 let label = tab.textLabel; 93 let bounds = label.getBoundingClientRect(); 94 95 await SpecialPowers.spawn(browser, [], () => { 96 let link = content.document.createElement("link"); 97 link.setAttribute("href", "file_favicon.png"); 98 link.setAttribute("rel", "icon"); 99 link.setAttribute("type", "image/png"); 100 content.document.head.appendChild(link); 101 }); 102 103 ok( 104 !tab.hasAttribute("pendingicon"), 105 "Should not have marked a pending icon" 106 ); 107 let newBounds = label.getBoundingClientRect(); 108 is( 109 bounds.x, 110 newBounds.left, 111 "Should have seen the title in the same place." 112 ); 113 114 await waitForPendingIcon(); 115 116 ok( 117 !tab.hasAttribute("pendingicon"), 118 "Should not have marked a pending icon" 119 ); 120 newBounds = label.getBoundingClientRect(); 121 is( 122 bounds.x, 123 newBounds.left, 124 "Should have seen the title in the same place." 125 ); 126 127 icon = await waitForFaviconMessage(true); 128 is( 129 icon.iconURL, 130 TEST_PATH + "file_favicon.png", 131 "Should have loaded the new icon." 132 ); 133 134 ok( 135 !tab.hasAttribute("pendingicon"), 136 "Should not have marked a pending icon" 137 ); 138 newBounds = label.getBoundingClientRect(); 139 is( 140 bounds.x, 141 newBounds.left, 142 "Should have seen the title in the same place." 143 ); 144 } 145 ); 146 }); 147 148 // Verify that pinned tabs don't change size when an icon is pending. 149 add_task(async () => { 150 await BrowserTestUtils.withNewTab( 151 { gBrowser, url: "about:blank" }, 152 async browser => { 153 let tab = gBrowser.getTabForBrowser(browser); 154 gBrowser.pinTab(tab); 155 156 let bounds = tab.getBoundingClientRect(); 157 BrowserTestUtils.startLoadingURIString( 158 browser, 159 TEST_PATH + "file_with_slow_favicon.html" 160 ); 161 162 await waitForAttributeChange(tab, "label"); 163 ok(tab.hasAttribute("busy"), "Should have seen the busy attribute"); 164 let label = tab.textLabel; 165 ok(label.textContent.includes("file_with_slow_favicon.html")); 166 let newBounds = tab.getBoundingClientRect(); 167 is( 168 bounds.width, 169 newBounds.width, 170 "Should have seen tab remain the same size." 171 ); 172 173 await waitForAttributeChange(tab, "busy"); 174 ok( 175 !tab.hasAttribute("busy"), 176 "Should have seen the busy attribute removed" 177 ); 178 newBounds = tab.getBoundingClientRect(); 179 is( 180 bounds.width, 181 newBounds.width, 182 "Should have seen tab remain the same size." 183 ); 184 185 await waitForFaviconMessage(true); 186 newBounds = tab.getBoundingClientRect(); 187 is( 188 bounds.width, 189 newBounds.width, 190 "Should have seen tab remain the same size." 191 ); 192 } 193 ); 194 });