test_animated_css_image.html (4040B)
1 <!doctype html> 2 <script src="/tests/SimpleTest/SimpleTest.js"></script> 3 <script src="/tests/SimpleTest/WindowSnapshot.js"></script> 4 <!-- 5 scrolling=no is just paranoia to ensure that we don't get invalidations 6 due to scrollbars 7 --> 8 <iframe scrolling="no" id="iframe"></iframe> 9 <!-- this contains the kTests array --> 10 <script src="animated_image_test_list.js"></script> 11 <script> 12 SimpleTest.waitForExplicitFinish(); 13 14 /* 15 * This test duplicates image/test/browser/browser_animated_css_image.js, so keep them in sync. 16 * This is because we need a browser-chrome test in order to test invalidation (the getSnapshot method there 17 * uses the same path as painting to the screen, whereas here we are doing a 18 * separate paint to a surface), but browser-chrome isn't run on android, so test_animated_css_image.html 19 * gets us android coverage. 20 */ 21 22 23 // We hit an optimized path in WebRender that doesn't cause a repaint on the 24 // main thread: 25 // 26 // https://searchfox.org/mozilla-central/rev/b7f3977978922d44c7d92ae01c0d4cc2baca7bc2/layout/style/ImageLoader.cpp#553 27 // 28 // So our assertions and polling need to be a bit weaker on WR. 29 const kUsingWebRender = SpecialPowers.DOMWindowUtils.layerManagerType.startsWith("WebRender"); 30 31 let iframe = document.getElementById("iframe"); 32 let blankSnapshot; 33 34 async function assertAnimates(html, getExpectedRepaintedElement) { 35 const kExpectEqual = true; 36 const kNumRetries = kUsingWebRender ? 600 : 30; 37 38 info("testing: " + html); 39 40 { 41 let load = new Promise(resolve => { 42 iframe.addEventListener("load", resolve, { once: true }); 43 }); 44 iframe.srcdoc = html; 45 await load; 46 } 47 48 // This ensures the MozAfterPaint events come through as expected. 49 await SimpleTest.promiseFocus(iframe.contentWindow); 50 51 let initial = await snapshotWindow(iframe.contentWindow); 52 53 let repaintedElement = getExpectedRepaintedElement(iframe.contentDocument); 54 if (!kUsingWebRender) { 55 // Ensure the painted state is clear before we start polling. 56 SpecialPowers.DOMWindowUtils.checkAndClearPaintedState(repaintedElement); 57 } 58 59 { 60 let [equal, s1 /* , s2, differentPixels, maxDiff */] = compareSnapshots(initial, blankSnapshot, kExpectEqual); 61 ok(!equal, "Initial snapshot shouldn't be blank"); 62 info(s1); 63 } 64 65 let foundDifferent = false; 66 let foundInitialAgain = false; 67 for (let i = 0; i < kNumRetries; ++i) { 68 let current = await snapshotWindow(iframe.contentWindow); 69 let [equal, /* s1 */, s2 /* , differentPixels, maxDiff */ ] = compareSnapshots(initial, current, kExpectEqual); 70 if (!foundDifferent && !equal) { 71 ok(true, `Found different image after ${i} retries`); 72 ok(kUsingWebRender || SpecialPowers.DOMWindowUtils.checkAndClearPaintedState(repaintedElement), "Should've repainted the expected element"); 73 info(s2); 74 foundDifferent = true; 75 } 76 77 // Ensure that we go back to the initial state (animated1.gif) is an 78 // infinite gif. 79 if (foundDifferent && equal) { 80 ok(true, `Found same image again after ${i} retries`); 81 ok(kUsingWebRender || SpecialPowers.DOMWindowUtils.checkAndClearPaintedState(repaintedElement), "Should've repainted the expected element"); 82 foundInitialAgain = true; 83 break; 84 } 85 86 await new Promise(resolve => { 87 if (kUsingWebRender) { 88 requestAnimationFrame(() => { 89 requestAnimationFrame(resolve); 90 }); 91 } else { 92 iframe.contentWindow.addEventListener("MozAfterPaint", resolve, { once: true }); 93 } 94 }); 95 } 96 97 ok(foundDifferent && foundInitialAgain, `Should've found a different snapshot and then an equal one, after ${kNumRetries} retries`); 98 } 99 100 onload = async function() { 101 // First snapshot the blank window. 102 blankSnapshot = await snapshotWindow(iframe.contentWindow); 103 104 // kTests is defined in the imported animated_image_test_list.js so it can 105 // be shared between tests. 106 // eslint-disable-next-line no-undef 107 for (let { html, element } of kTests) 108 await assertAnimates(html, element); 109 110 SimpleTest.finish(); 111 } 112 </script>