browser_bug1701027-2.js (5027B)
1 /* This test is based on 2 https://searchfox.org/mozilla-central/rev/e082df56bbfeaff0f388e7da9da401ff414df18f/gfx/layers/apz/test/mochitest/browser_test_select_zoom.js 3 */ 4 5 // In order for this test to test the original bug we need: 6 // 1) At least e10s enabled so that apz is enabled so we can create an 7 // nsDisplayAsyncZoom item 8 // (the insertion of this item without marking the required frame modified 9 // is what causes the bug in the retained display list merging) 10 // 2) a root content document, again so that we can create a nsDisplayAsyncZoom 11 // item 12 // 3) the root content document cannot have a display port to start 13 // (if it has a display port then it gets a nsDisplayAsyncZoom, but we need 14 // that to be created after the anonymous content we insert into the 15 // document) 16 // Point 3) requires the root content document to be in the parent process, 17 // since if it is in a content process it will get a displayport for being at 18 // the root of a process. 19 // Creating an in-process root content document I think is not possible in 20 // mochitest-plain. mochitest-chrome does not have e10s enabled. So this has to 21 // be a mochitest-browser-chrome test. 22 23 // Outline of this test: 24 // Open a new tab with a pretty simple content file, that is not scrollable 25 // Use the anonymous content api to insert into that content doc 26 // Set a displayport on the root scroll frame of the content doc directly. 27 // Then we have to be careful not to do anything that causes a full display 28 // list rebuild. 29 // And finally we change the color of the fixed element which covers the whole 30 // viewport which causes us to do a partial display list update including the 31 // anonymous content, which hits the assert we are aiming to test. 32 33 add_task(async function () { 34 function getChromeURL(filename) { 35 let chromeURL = getRootDirectory(gTestPath) + filename; 36 return chromeURL; 37 } 38 39 // We need this otherwise there is a burst animation on the new tab when it 40 // loads and that somehow scrolls a scroll frame, which makes it active, 41 // which makes the scrolled frame an AGR, which means we have multiple AGRs 42 // (the display port makes the root scroll frame active and an AGR) so we hit 43 // this 44 // https://searchfox.org/mozilla-central/rev/e082df56bbfeaff0f388e7da9da401ff414df18f/layout/painting/RetainedDisplayListBuilder.cpp#1179 45 // and are forced to do a full display list rebuild and that prevents us from 46 // testing the original bug. 47 await SpecialPowers.pushPrefEnv({ 48 set: [["ui.prefersReducedMotion", 1]], 49 }); 50 51 const pageUrl = getChromeURL("helper_bug1701027-2.html"); 52 let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, pageUrl); 53 54 const [theX, theY] = await SpecialPowers.spawn( 55 tab.linkedBrowser, 56 [], 57 async () => { 58 content.document.body.offsetWidth; 59 60 await new Promise(r => content.window.requestAnimationFrame(r)); 61 62 const rect = content.document 63 .getElementById("fd") 64 .getBoundingClientRect(); 65 const x = content.window.mozInnerScreenX + rect.left + rect.width / 2; 66 const y = content.window.mozInnerScreenY + rect.top + rect.height / 2; 67 68 let doc = SpecialPowers.wrap(content.document); 69 var bq = doc.createElement("blockquote"); 70 bq.textContent = "This blockquote text."; 71 var div = doc.createElement("div"); 72 div.textContent = " This div text."; 73 bq.appendChild(div); 74 var ac = doc.insertAnonymousContent(bq); 75 content.document.body.offsetWidth; 76 77 await new Promise(r => content.window.requestAnimationFrame(r)); 78 await new Promise(r => content.window.requestAnimationFrame(r)); 79 80 content.window.windowUtils.setDisplayPortMarginsForElement( 81 0, 82 0, 83 0, 84 0, 85 doc.documentElement, 86 1 87 ); 88 content.window.windowUtils.setDisplayPortBaseForElement( 89 0, 90 0, 91 100, 92 100, 93 doc.documentElement 94 ); 95 96 await new Promise(r => content.window.requestAnimationFrame(r)); 97 await new Promise(r => content.window.requestAnimationFrame(r)); 98 99 return [x, y]; 100 } 101 ); 102 103 await SpecialPowers.spawn(tab.linkedBrowser, [], async () => { 104 content.document.getElementById("fd").style.backgroundColor = "blue"; 105 }); 106 107 await new Promise(resolve => setTimeout(resolve, 0)); 108 await SpecialPowers.spawn(tab.linkedBrowser, [], async () => { 109 await new Promise(r => content.window.requestAnimationFrame(r)); 110 await new Promise(r => content.window.requestAnimationFrame(r)); 111 }); 112 113 await SpecialPowers.spawn(tab.linkedBrowser, [], async () => { 114 content.document.getElementById("fd").style.backgroundColor = "red"; 115 }); 116 117 await new Promise(resolve => setTimeout(resolve, 0)); 118 await SpecialPowers.spawn(tab.linkedBrowser, [], async () => { 119 await new Promise(r => content.window.requestAnimationFrame(r)); 120 await new Promise(r => content.window.requestAnimationFrame(r)); 121 }); 122 123 BrowserTestUtils.removeTab(tab); 124 125 ok(true, "didn't crash"); 126 });