Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

<!doctype html>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/WindowSnapshot.js"></script>
<!--
scrolling=no is just paranoia to ensure that we don't get invalidations
due to scrollbars
-->
<iframe scrolling="no" id="iframe"></iframe>
<script>
SimpleTest.waitForExplicitFinish();
// We hit an optimized path in WebRender that doesn't cause a repaint on the
// main thread:
//
//
// So our assertions and polling need to be a bit weaker on WR.
const kUsingWebRender = SpecialPowers.DOMWindowUtils.layerManagerType.startsWith("WebRender");
let iframe = document.getElementById("iframe");
let blankSnapshot;
async function assertAnimates(html, getExpectedRepaintedElement) {
const kExpectEqual = true;
const kNumRetries = kUsingWebRender ? 600 : 30;
info("testing: " + html);
{
let load = new Promise(resolve => {
iframe.addEventListener("load", resolve, { once: true });
});
iframe.srcdoc = html;
await load;
}
// This ensures the MozAfterPaint events come through as expected.
await SimpleTest.promiseFocus(iframe.contentWindow);
let initial = await snapshotWindow(iframe.contentWindow);
let repaintedElement = getExpectedRepaintedElement(iframe.contentDocument);
if (!kUsingWebRender) {
// Ensure the painted state is clear before we start polling.
SpecialPowers.DOMWindowUtils.checkAndClearPaintedState(repaintedElement);
}
{
let [equal, s1 /* , s2, differentPixels, maxDiff */] = compareSnapshots(initial, blankSnapshot, kExpectEqual);
ok(!equal, "Initial snapshot shouldn't be blank");
info(s1);
}
let foundDifferent = false;
let foundInitialAgain = false;
for (let i = 0; i < kNumRetries; ++i) {
let current = await snapshotWindow(iframe.contentWindow);
let [equal, /* s1 */, s2 /* , differentPixels, maxDiff */ ] = compareSnapshots(initial, current, kExpectEqual);
if (!foundDifferent && !equal) {
ok(true, `Found different image after ${i} retries`);
ok(kUsingWebRender || SpecialPowers.DOMWindowUtils.checkAndClearPaintedState(repaintedElement), "Should've repainted the expected element");
info(s2);
foundDifferent = true;
}
// Ensure that we go back to the initial state (animated1.gif) is an
// infinite gif.
if (foundDifferent && equal) {
ok(true, `Found same image again after ${i} retries`);
ok(kUsingWebRender || SpecialPowers.DOMWindowUtils.checkAndClearPaintedState(repaintedElement), "Should've repainted the expected element");
foundInitialAgain = true;
break;
}
await new Promise(resolve => {
if (kUsingWebRender) {
requestAnimationFrame(() => {
requestAnimationFrame(resolve);
});
} else {
iframe.contentWindow.addEventListener("MozAfterPaint", resolve, { once: true });
}
});
}
ok(foundDifferent && foundInitialAgain, `Should've found a different snapshot and then an equal one, after ${kNumRetries} retries`);
}
const kTests = [
// Sanity test: background-image on a regular element.
{
html: `
<!doctype html>
<style>
div {
width: 100px;
height: 100px;
background-image: url(animated1.gif);
}
</style>
<div></div>
`,
element(doc) {
return doc.querySelector("div");
},
},
// bug 1627585: content: url()
{
html: `
<!doctype html>
<style>
div::before {
content: url(animated1.gif);
}
</style>
<div></div>
`,
element(doc) {
return doc.querySelector("div");
},
},
// bug 1627585: content: url() (on an element directly)
{
html: `
<!doctype html>
<style>
div {
content: url(animated1.gif);
}
</style>
<div></div>
`,
element(doc) {
return doc.querySelector("div");
},
},
// bug 1625571: background propagated to canvas.
{
html: `
<!doctype html>
<style>
body {
background-image: url(animated1.gif);
}
</style>
`,
element(doc) {
return doc.documentElement;
},
},
// bug 1719375: CSS animation in SVG image.
{
html: `
<!doctype html>
<style>
div {
width: 100px;
height: 100px;
background-image: url(animated1.svg);
}
</style>
<div></div>
`,
element(doc) {
return doc.querySelector("div");
},
},
// bug 1730834: stopped window.
{
html: `
<!doctype html>
<style>
div {
width: 100px;
height: 100px;
}
</style>
<body onload="window.stop(); document.querySelector('div').style.backgroundImage = 'url(animated1.gif)';">
<div></div>
</body>
`,
element(doc) {
return doc.querySelector("div");
},
},
// bug 1731138: Animated mask
{
html: `
<!doctype html>
<style>
div {
width: 100px;
height: 100px;
background-color: lime;
mask-clip: border-box;
mask-size: 100% 100%;
mask-image: url(animatedMask.gif);
}
</style>
<div></div>
`,
element(doc) {
return doc.querySelector("div");
},
},
];
onload = async function() {
// First snapshot the blank window.
blankSnapshot = await snapshotWindow(iframe.contentWindow);
for (let { html, element } of kTests)
await assertAnimates(html, element);
SimpleTest.finish();
}
</script>