browser_animated_css_image.js (5359B)
1 /* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */ 2 /* vim: set sts=2 sw=2 et tw=80: */ 3 /* 4 * This test duplicates image/test/mochitest/test_animated_css_image.html, so keep them in sync. 5 * This is because we need a browser-chrome test in order to test invalidation (the getSnapshot method here 6 * uses the same path as painting to the screen, whereas test_animated_css_image.html is doing a 7 * separate paint to a surface), but browser-chrome isn't run on android, so test_animated_css_image.html 8 * gets us android coverage. 9 */ 10 11 /* This test is based on 12 https://searchfox.org/mozilla-central/rev/25d26b0a62cc5bb4aa3bb90a11f3b0b7c52859c4/gfx/layers/apz/test/mochitest/browser_test_position_sticky.js 13 */ 14 15 "use strict"; 16 17 requestLongerTimeout(3); 18 19 Services.scriptloader.loadSubScript( 20 "chrome://mochitests/content/browser/gfx/layers/apz/test/mochitest/apz_test_utils.js", 21 this 22 ); 23 24 Services.scriptloader.loadSubScript( 25 "chrome://mochitests/content/browser/gfx/layers/apz/test/mochitest/apz_test_native_event_utils.js", 26 this 27 ); 28 29 // this contains the kTests array 30 Services.scriptloader.loadSubScript( 31 "chrome://mochitests/content/browser/image/test/browser/animated_image_test_list.js", 32 this 33 ); 34 35 async function assertAnimates(thehtml) { 36 function httpURL(sfilename) { 37 let chromeURL = getRootDirectory(gTestPath) + sfilename; 38 return chromeURL.replace( 39 "chrome://mochitests/content/", 40 "http://mochi.test:8888/" 41 ); 42 } 43 44 const url = httpURL("helper_animated_css_image.html"); 45 const tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url); 46 47 const { rect } = await SpecialPowers.spawn( 48 tab.linkedBrowser, 49 [], 50 async () => { 51 let rect = content.document.documentElement.getBoundingClientRect(); 52 rect.x += content.window.mozInnerScreenX; 53 rect.y += content.window.mozInnerScreenY; 54 55 return { 56 rect, 57 }; 58 } 59 ); 60 61 let blankSnapshot = await getSnapshot({ 62 x: rect.x, 63 y: rect.y, 64 width: rect.width, 65 height: rect.height, 66 }); 67 68 const kNumRetries = 600; 69 70 info("testing: " + thehtml); 71 72 await SpecialPowers.spawn(tab.linkedBrowser, [thehtml], async thehtml => { 73 const theiframe = content.document.getElementById("iframe"); 74 let load = new Promise(resolve => { 75 theiframe.addEventListener("load", resolve, { once: true }); 76 }); 77 theiframe.srcdoc = thehtml; 78 await load; 79 80 // give time for content/test load handlers to run before we do anything 81 await new Promise(resolve => { 82 content.window.requestAnimationFrame(() => { 83 content.window.requestAnimationFrame(resolve); 84 }); 85 }); 86 87 // make sure we are flushed and rendered. 88 content.document.documentElement.getBoundingClientRect(); 89 90 await new Promise(resolve => { 91 content.window.requestAnimationFrame(() => { 92 content.window.requestAnimationFrame(resolve); 93 }); 94 }); 95 }); 96 97 let initial = await getSnapshot({ 98 x: rect.x, 99 y: rect.y, 100 width: rect.width, 101 height: rect.height, 102 }); 103 104 { 105 // One test (bug 1730834) loads an image as the background of a div in the 106 // load handler, so there's no good way to wait for it to be loaded and 107 // rendered except to poll. 108 let equal = initial == blankSnapshot; 109 for (let i = 0; i < kNumRetries; ++i) { 110 if (!equal) { 111 break; 112 } 113 114 await SpecialPowers.spawn(tab.linkedBrowser, [], async () => { 115 await new Promise(resolve => { 116 content.window.requestAnimationFrame(() => { 117 content.window.requestAnimationFrame(resolve); 118 }); 119 }); 120 }); 121 122 initial = await getSnapshot({ 123 x: rect.x, 124 y: rect.y, 125 width: rect.width, 126 height: rect.height, 127 }); 128 equal = initial == blankSnapshot; 129 } 130 ok(!equal, "Initial snapshot shouldn't be blank"); 131 } 132 133 async function checkFrames() { 134 let foundDifferent = false; 135 let foundInitialAgain = false; 136 for (let i = 0; i < kNumRetries; ++i) { 137 let current = await getSnapshot({ 138 x: rect.x, 139 y: rect.y, 140 width: rect.width, 141 height: rect.height, 142 }); 143 144 let equal = initial == current; 145 if (!foundDifferent && !equal) { 146 ok(true, `Found different image after ${i} retries`); 147 foundDifferent = true; 148 } 149 150 // Ensure that we go back to the initial state (animated1.gif) is an 151 // infinite gif. 152 if (foundDifferent && equal) { 153 ok(true, `Found same image again after ${i} retries`); 154 155 foundInitialAgain = true; 156 break; 157 } 158 159 await SpecialPowers.spawn(tab.linkedBrowser, [], async () => { 160 await new Promise(resolve => { 161 content.window.requestAnimationFrame(() => { 162 content.window.requestAnimationFrame(resolve); 163 }); 164 }); 165 }); 166 } 167 168 ok( 169 foundDifferent && foundInitialAgain, 170 `Should've found a different snapshot and then an equal one, after ${kNumRetries} retries` 171 ); 172 } 173 174 for (let j = 0; j < 5; j++) { 175 await checkFrames(); 176 } 177 178 BrowserTestUtils.removeTab(tab); 179 } 180 181 add_task(async () => { 182 // kTests is defined in the imported animated_image_test_list.js so it can 183 // be shared between tests. 184 // eslint-disable-next-line no-undef 185 for (let { html } of kTests) { 186 await assertAnimates(html); 187 } 188 });