browser_test_background_tab_load_scroll.js (4185B)
1 Services.scriptloader.loadSubScript( 2 "chrome://mochitests/content/browser/gfx/layers/apz/test/mochitest/apz_test_utils.js", 3 this 4 ); 5 6 Services.scriptloader.loadSubScript( 7 "chrome://mochitests/content/browser/gfx/layers/apz/test/mochitest/apz_test_native_event_utils.js", 8 this 9 ); 10 11 add_task(async function test_main() { 12 // Open a specific page in a background tab, then switch to the tab, check if 13 // the visual and layout scroll offsets have diverged. 14 // Then change to another tab so it's background again. Then reload it. Then 15 // change back to it and check again if the visual and layout scroll offsets 16 // have diverged. 17 // The page has a couple important properties to trigger the bug. We need to 18 // be restoring a non-zero scroll position so that we call ScrollToImpl with 19 // origin restore so that we do not set the visual viewport offset. We then 20 // need to call ScrollToImpl with a origin that does not get clobber by apz 21 // so that we (wrongly) set the visual viewport offset. 22 23 requestLongerTimeout(2); 24 25 async function twoRafsInContent(browser) { 26 await SpecialPowers.spawn(browser, [], async function () { 27 await new Promise(r => 28 content.requestAnimationFrame(() => content.requestAnimationFrame(r)) 29 ); 30 }); 31 } 32 33 async function waitForApzInContent(browser) { 34 await SpecialPowers.spawn(browser, [], async () => { 35 await content.wrappedJSObject.waitUntilApzStable(); 36 await content.wrappedJSObject.promiseApzFlushedRepaints(); 37 }); 38 } 39 40 async function checkScrollPosInContent(browser, iter, reload) { 41 let visualScrollPos = await SpecialPowers.spawn(browser, [], function () { 42 const offsetX = {}; 43 const offsetY = {}; 44 SpecialPowers.getDOMWindowUtils(content).getVisualViewportOffset( 45 offsetX, 46 offsetY 47 ); 48 return offsetY.value; 49 }); 50 51 let scrollPos = await SpecialPowers.spawn(browser, [], function () { 52 return content.window.scrollY; 53 }); 54 55 // When this fails the difference is at least 10000. 56 ok( 57 Math.abs(scrollPos - visualScrollPos) < 2, 58 "expect scroll position and visual scroll position to be the same: visual " + 59 visualScrollPos + 60 " scroll " + 61 scrollPos + 62 " (" + 63 iter + 64 (reload ? reload : "") + 65 ")" 66 ); 67 68 // After reload, the scroll position should be doubled since the target 69 // document calls `scrollBy(0, 10000)` after restoring the previous scroll 70 // position `(0, 10000)`. 71 is(scrollPos, 10000 * (reload === "reload" ? 2 : 1)); 72 } 73 74 for (let i = 0; i < 5; i++) { 75 let blankurl = "about:blank"; 76 let blankTab = BrowserTestUtils.addTab(gBrowser, blankurl); 77 let blankbrowser = blankTab.linkedBrowser; 78 await BrowserTestUtils.browserLoaded(blankbrowser, false, blankurl); 79 80 let url = 81 "http://mochi.test:8888/browser/gfx/layers/apz/test/mochitest/helper_background_tab_load_scroll.html"; 82 let backgroundTab = BrowserTestUtils.addTab(gBrowser, url); 83 let browser = backgroundTab.linkedBrowser; 84 await BrowserTestUtils.browserLoaded(browser, false, url); 85 dump("Done loading background tab\n"); 86 87 await twoRafsInContent(browser); 88 89 // Switch to the foreground. 90 await BrowserTestUtils.switchTab(gBrowser, backgroundTab); 91 dump("Switched background tab to foreground\n"); 92 93 await waitForApzInContent(browser); 94 95 await checkScrollPosInContent(browser, i); 96 97 await BrowserTestUtils.switchTab(gBrowser, blankTab); 98 99 browser.reload(); 100 await BrowserTestUtils.browserLoaded(browser, false, url); 101 102 await twoRafsInContent(browser); 103 104 // Switch to the foreground. 105 await BrowserTestUtils.switchTab(gBrowser, backgroundTab); 106 dump("Switched background tab to foreground\n"); 107 108 await waitForApzInContent(browser); 109 110 await checkScrollPosInContent(browser, i, "reload"); 111 112 // Cleanup 113 let tabClosed = BrowserTestUtils.waitForTabClosing(backgroundTab); 114 BrowserTestUtils.removeTab(backgroundTab); 115 await tabClosed; 116 117 let blanktabClosed = BrowserTestUtils.waitForTabClosing(blankTab); 118 BrowserTestUtils.removeTab(blankTab); 119 await blanktabClosed; 120 } 121 });