зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1305325 - Part 15: Tests composed style for missing keyframe for properties runnning on the compositor. r=birtles
The error value, 0.01, used in this test is the same as we used in test_animation_omta.html. MozReview-Commit-ID: 50g3k43yAgu
This commit is contained in:
Родитель
b98aba8d33
Коммит
d2f7b668f9
|
@ -54,6 +54,7 @@ support-files =
|
|||
style/file_animation-setting-effect.html
|
||||
style/file_animation-setting-spacing.html
|
||||
style/file_missing-keyframe.html
|
||||
style/file_missing-keyframe-on-compositor.html
|
||||
testcommon.js
|
||||
|
||||
[css-animations/test_animations-dynamic-changes.html]
|
||||
|
@ -109,3 +110,4 @@ skip-if = toolkit == 'android'
|
|||
[style/test_animation-setting-effect.html]
|
||||
[style/test_animation-setting-spacing.html]
|
||||
[style/test_missing-keyframe.html]
|
||||
[style/test_missing-keyframe-on-compositor.html]
|
||||
|
|
|
@ -0,0 +1,476 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<script src="../testcommon.js"></script>
|
||||
<script src="/tests/SimpleTest/paint_listener.js"></script>
|
||||
<style>
|
||||
div {
|
||||
/* Element needs geometry to be eligible for layerization */
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background-color: white;
|
||||
}
|
||||
</style>
|
||||
<body>
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
if (!SpecialPowers.DOMWindowUtils.layerManagerRemote ||
|
||||
!SpecialPowers.getBoolPref(
|
||||
'layers.offmainthreadcomposition.async-animations')) {
|
||||
// If OMTA is disabled, nothing to run.
|
||||
done();
|
||||
}
|
||||
|
||||
function waitForPaintsFlushed() {
|
||||
return new Promise(function(resolve, reject) {
|
||||
waitForAllPaintsFlushed(resolve);
|
||||
});
|
||||
}
|
||||
|
||||
// Note that promise tests run in sequence so this ensures the document is
|
||||
// loaded before any of the other tests run.
|
||||
promise_test(t => {
|
||||
// Without this, the first test case fails on Android.
|
||||
return waitForDocumentLoad();
|
||||
}, 'Ensure document has been loaded');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
|
||||
var div = addDiv(t, { style: 'opacity: 0.1' });
|
||||
div.animate({ opacity: 1 }, 100 * MS_PER_SEC);
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
var opacity =
|
||||
SpecialPowers.DOMWindowUtils.getOMTAStyle(div, 'opacity');
|
||||
assert_equals(opacity, '0.1',
|
||||
'The initial opacity value should be the base value');
|
||||
});
|
||||
}, 'Initial opacity value for animation with no no keyframe at offset 0');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
|
||||
var div = addDiv(t, { style: 'opacity: 0.1' });
|
||||
div.animate({ opacity: [ 0.5, 1 ] }, 100 * MS_PER_SEC);
|
||||
div.animate({ opacity: 1 }, 100 * MS_PER_SEC);
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
var opacity =
|
||||
SpecialPowers.DOMWindowUtils.getOMTAStyle(div, 'opacity');
|
||||
assert_equals(opacity, '0.5',
|
||||
'The initial opacity value should be the value of ' +
|
||||
'lower-priority animation value');
|
||||
});
|
||||
}, 'Initial opacity value for animation with no keyframe at offset 0 when ' +
|
||||
'there is a lower-priority animation');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
|
||||
var div =
|
||||
addDiv(t, { style: 'opacity: 0.1; transition: opacity 100s linear' });
|
||||
getComputedStyle(div).opacity;
|
||||
|
||||
div.style.opacity = '0.5';
|
||||
div.animate({ opacity: 1 }, 100 * MS_PER_SEC);
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
var opacity =
|
||||
SpecialPowers.DOMWindowUtils.getOMTAStyle(div, 'opacity');
|
||||
assert_equals(opacity, '0.1',
|
||||
'The initial opacity value should be the initial value of ' +
|
||||
'the transition');
|
||||
});
|
||||
}, 'Initial opacity value for animation with no keyframe at offset 0 when ' +
|
||||
'there is a transition on the same property');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
|
||||
var div = addDiv(t, { style: 'opacity: 0' });
|
||||
div.animate([{ offset: 0, opacity: 1 }], 100 * MS_PER_SEC);
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(50 * MS_PER_SEC);
|
||||
|
||||
var opacity =
|
||||
SpecialPowers.DOMWindowUtils.getOMTAStyle(div, 'opacity');
|
||||
assert_equals(opacity, '0.5',
|
||||
'Opacity value at 50% should be composed onto the base ' +
|
||||
'value');
|
||||
});
|
||||
}, 'Opacity value for animation with no keyframe at offset 1 at 50% ');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
|
||||
var div = addDiv(t, { style: 'opacity: 0' });
|
||||
div.animate({ opacity: [ 0.5, 0.5 ] }, 100 * MS_PER_SEC);
|
||||
div.animate([{ offset: 0, opacity: 1 }], 100 * MS_PER_SEC);
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(50 * MS_PER_SEC);
|
||||
|
||||
var opacity =
|
||||
SpecialPowers.DOMWindowUtils.getOMTAStyle(div, 'opacity');
|
||||
assert_equals(opacity, '0.75', // (0.5 + 1) * 0.5
|
||||
'Opacity value at 50% should be composed onto the value ' +
|
||||
'of middle of lower-priority animation');
|
||||
});
|
||||
}, 'Opacity value for animation with no keyframe at offset 1 at 50% when ' +
|
||||
'there is a lower-priority animation');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
|
||||
var div =
|
||||
addDiv(t, { style: 'opacity: 0; transition: opacity 100s linear' });
|
||||
getComputedStyle(div).opacity;
|
||||
|
||||
div.style.opacity = '0.5';
|
||||
div.animate([{ offset: 0, opacity: 1 }], 100 * MS_PER_SEC);
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(50 * MS_PER_SEC);
|
||||
|
||||
var opacity =
|
||||
SpecialPowers.DOMWindowUtils.getOMTAStyle(div, 'opacity');
|
||||
assert_equals(opacity, '0.625', // ((0 + 0.5) * 0.5 + 1) * 0.5
|
||||
'Opacity value at 50% should be composed onto the value ' +
|
||||
'of middle of transition');
|
||||
});
|
||||
}, 'Opacity value for animation with no keyframe at offset 1 at 50% when ' +
|
||||
'there is a transition on the same property');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
|
||||
var div = addDiv(t);
|
||||
var lowerAnimation = div.animate({ opacity: [ 0.5, 1 ] }, 100 * MS_PER_SEC);
|
||||
var higherAnimation = div.animate({ opacity: 1 }, 100 * MS_PER_SEC);
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
lowerAnimation.pause();
|
||||
return waitForPaintsFlushed();
|
||||
}).then(() => {
|
||||
SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(50 * MS_PER_SEC);
|
||||
|
||||
var opacity =
|
||||
SpecialPowers.DOMWindowUtils.getOMTAStyle(div, 'opacity');
|
||||
// The underlying value is the value that is staying at 0ms of the
|
||||
// lowerAnimation, that is 0.5.
|
||||
// (0.5 + 1.0) * (50 * MS_PER_SEC / 100 * MS_PER_SEC) = 0.75.
|
||||
assert_equals(opacity, '0.75',
|
||||
'Composed opacity value should be composed onto the value ' +
|
||||
'of lower-priority paused animation');
|
||||
});
|
||||
}, 'Opacity value for animation with no keyframe at offset 0 at 50% when ' +
|
||||
'composed onto a paused underlying animation');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
|
||||
var div = addDiv(t);
|
||||
var lowerAnimation = div.animate({ opacity: [ 0.5, 1 ] }, 100 * MS_PER_SEC);
|
||||
var higherAnimation = div.animate({ opacity: 1 }, 100 * MS_PER_SEC);
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
lowerAnimation.playbackRate = 0;
|
||||
return waitForPaintsFlushed();
|
||||
}).then(() => {
|
||||
SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(50 * MS_PER_SEC);
|
||||
|
||||
var opacity =
|
||||
SpecialPowers.DOMWindowUtils.getOMTAStyle(div, 'opacity');
|
||||
// The underlying value is the value that is staying at 0ms of the
|
||||
// lowerAnimation, that is 0.5.
|
||||
// (0.5 + 1.0) * (50 * MS_PER_SEC / 100 * MS_PER_SEC) = 0.75.
|
||||
assert_equals(opacity, '0.75',
|
||||
'Composed opacity value should be composed onto the value ' +
|
||||
'of lower-priority zero playback rate animation');
|
||||
});
|
||||
}, 'Opacity value for animation with no keyframe at offset 0 at 50% when ' +
|
||||
'composed onto a zero playback rate underlying animation');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
|
||||
var div = addDiv(t);
|
||||
var lowerAnimation = div.animate({ opacity: [ 1, 0.5 ] }, 100 * MS_PER_SEC);
|
||||
var higherAnimation = div.animate({ opacity: 1 }, 100 * MS_PER_SEC);
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
lowerAnimation.effect.timing.duration = 0;
|
||||
lowerAnimation.effect.timing.fill = 'forwards';
|
||||
return waitForPaintsFlushed();
|
||||
}).then(() => {
|
||||
SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(50 * MS_PER_SEC);
|
||||
|
||||
var opacity =
|
||||
SpecialPowers.DOMWindowUtils.getOMTAStyle(div, 'opacity');
|
||||
// The underlying value is the value that is filling forwards state of the
|
||||
// lowerAnimation, that is 0.5.
|
||||
// (0.5 + 1.0) * (50 * MS_PER_SEC / 100 * MS_PER_SEC) = 0.75.
|
||||
assert_equals(opacity, '0.75',
|
||||
'Composed opacity value should be composed onto the value ' +
|
||||
'of lower-priority zero active duration animation');
|
||||
});
|
||||
}, 'Opacity value for animation with no keyframe at offset 0 at 50% when ' +
|
||||
'composed onto a zero active duration underlying animation');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
|
||||
var div = addDiv(t, { style: 'transform: translateX(100px)' });
|
||||
div.animate({ transform: 'translateX(200px)' }, 100 * MS_PER_SEC);
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
var transform =
|
||||
SpecialPowers.DOMWindowUtils.getOMTAStyle(div, 'transform');
|
||||
assert_matrix_equals(transform, 'matrix(1, 0, 0, 1, 100, 0)',
|
||||
'The initial transform value should be the base value');
|
||||
});
|
||||
}, 'Initial transform value for animation with no keyframe at offset 0');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
|
||||
var div = addDiv(t, { style: 'transform: translateX(100px)' });
|
||||
div.animate({ transform: [ 'translateX(200px)', 'translateX(300px)' ] },
|
||||
100 * MS_PER_SEC);
|
||||
div.animate({ transform: 'translateX(400px)' }, 100 * MS_PER_SEC);
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
var transform =
|
||||
SpecialPowers.DOMWindowUtils.getOMTAStyle(div, 'transform');
|
||||
assert_matrix_equals(transform, 'matrix(1, 0, 0, 1, 200, 0)',
|
||||
'The initial transform value should be lower-priority animation value');
|
||||
});
|
||||
}, 'Initial transform value for animation with no keyframe at offset 0 when ' +
|
||||
'there is a lower-priority animation');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
|
||||
var div =
|
||||
addDiv(t, { style: 'transform: translateX(100px);' +
|
||||
'transition: transform 100s linear' });
|
||||
getComputedStyle(div).transform;
|
||||
|
||||
div.style.transform = 'translateX(200px)';
|
||||
div.animate({ transform: 'translateX(400px)' }, 100 * MS_PER_SEC);
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
var transform =
|
||||
SpecialPowers.DOMWindowUtils.getOMTAStyle(div, 'transform');
|
||||
assert_matrix_equals(transform, 'matrix(1, 0, 0, 1, 100, 0)',
|
||||
'The initial transform value should be the initial value of the ' +
|
||||
'transition');
|
||||
});
|
||||
}, 'Initial transform value for animation with no keyframe at offset 0 when ' +
|
||||
'there is a transition');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
|
||||
var div = addDiv(t, { style: 'transform: translateX(100px)' });
|
||||
div.animate([{ offset: 0, transform: 'translateX(200pX)' }],
|
||||
100 * MS_PER_SEC);
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(50 * MS_PER_SEC);
|
||||
|
||||
var transform =
|
||||
SpecialPowers.DOMWindowUtils.getOMTAStyle(div, 'transform');
|
||||
assert_matrix_equals(transform, 'matrix(1, 0, 0, 1, 150, 0)',
|
||||
'Transform value at 50% should be the base value');
|
||||
});
|
||||
}, 'Transform value for animation with no keyframe at offset 1 at 50%');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
|
||||
var div = addDiv(t, { style: 'transform: translateX(100px)' });
|
||||
div.animate({ transform: [ 'translateX(200px)', 'translateX(200px)' ] },
|
||||
100 * MS_PER_SEC);
|
||||
div.animate([{ offset: 0, transform: 'translateX(300px)' }],
|
||||
100 * MS_PER_SEC);
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(50 * MS_PER_SEC);
|
||||
|
||||
var transform =
|
||||
SpecialPowers.DOMWindowUtils.getOMTAStyle(div, 'transform');
|
||||
assert_matrix_equals(transform, 'matrix(1, 0, 0, 1, 250, 0)',
|
||||
'The final transform value should be the base value');
|
||||
});
|
||||
}, 'Transform value for animation with no keyframe at offset 1 at 50% when ' +
|
||||
'there is a lower-priority animation');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
|
||||
var div =
|
||||
addDiv(t, { style: 'transform: translateX(100px);' +
|
||||
'transition: transform 100s linear' });
|
||||
getComputedStyle(div).transform;
|
||||
|
||||
div.style.transform = 'translateX(200px)';
|
||||
div.animate([{ offset: 0, transform: 'translateX(300px)' }],
|
||||
100 * MS_PER_SEC);
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(50 * MS_PER_SEC);
|
||||
|
||||
var transform =
|
||||
SpecialPowers.DOMWindowUtils.getOMTAStyle(div, 'transform');
|
||||
// (150px + 300px) * 0.5
|
||||
assert_matrix_equals(transform, 'matrix(1, 0, 0, 1, 225, 0)',
|
||||
'The final transform value should be the final value of the transition');
|
||||
});
|
||||
}, 'Transform value for animation with no keyframe at offset 1 at 50% when ' +
|
||||
'there is a transition');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
|
||||
var div = addDiv(t);
|
||||
var lowerAnimation =
|
||||
div.animate({ transform: [ 'translateX(100px)', 'translateX(200px)' ] },
|
||||
100 * MS_PER_SEC);
|
||||
var higherAnimation = div.animate({ transform: 'translateX(300px)' },
|
||||
100 * MS_PER_SEC);
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
lowerAnimation.pause();
|
||||
return waitForPaintsFlushed();
|
||||
}).then(() => {
|
||||
SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(50 * MS_PER_SEC);
|
||||
|
||||
var transform =
|
||||
SpecialPowers.DOMWindowUtils.getOMTAStyle(div, 'transform');
|
||||
// The underlying value is the value that is staying at 0ms of the
|
||||
// lowerAnimation, that is 100px.
|
||||
// (100px + 300px) * (50 * MS_PER_SEC / 100 * MS_PER_SEC) = 200px.
|
||||
assert_matrix_equals(transform, 'matrix(1, 0, 0, 1, 200, 0)',
|
||||
'Composed transform value should be composed onto the value of ' +
|
||||
'lower-priority paused animation');
|
||||
});
|
||||
}, 'Transform value for animation with no keyframe at offset 0 at 50% when ' +
|
||||
'composed onto a paused underlying animation');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
|
||||
var div = addDiv(t);
|
||||
var lowerAnimation =
|
||||
div.animate({ transform: [ 'translateX(100px)', 'translateX(200px)' ] },
|
||||
100 * MS_PER_SEC);
|
||||
var higherAnimation = div.animate({ transform: 'translateX(300px)' },
|
||||
100 * MS_PER_SEC);
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
lowerAnimation.playbackRate = 0;
|
||||
return waitForPaintsFlushed();
|
||||
}).then(() => {
|
||||
SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(50 * MS_PER_SEC);
|
||||
|
||||
var transform =
|
||||
SpecialPowers.DOMWindowUtils.getOMTAStyle(div, 'transform');
|
||||
// The underlying value is the value that is staying at 0ms of the
|
||||
// lowerAnimation, that is 100px.
|
||||
// (100px + 300px) * (50 * MS_PER_SEC / 100 * MS_PER_SEC) = 200px.
|
||||
assert_matrix_equals(transform, 'matrix(1, 0, 0, 1, 200, 0)',
|
||||
'Composed transform value should be composed onto the value of ' +
|
||||
'lower-priority zero playback rate animation');
|
||||
});
|
||||
}, 'Transform value for animation with no keyframe at offset 0 at 50% when ' +
|
||||
'composed onto a zero playback rate underlying animation');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
|
||||
var div = addDiv(t);
|
||||
var lowerAnimation =
|
||||
div.animate({ transform: [ 'translateX(100px)', 'translateX(200px)' ] },
|
||||
{ duration: 10 * MS_PER_SEC,
|
||||
fill: 'forwards' });
|
||||
var higherAnimation = div.animate({ transform: 'translateX(300px)' },
|
||||
100 * MS_PER_SEC);
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(50 * MS_PER_SEC);
|
||||
|
||||
// We need to wait for a paint so that we can send the state of the lower
|
||||
// animation that is actually finished at this point.
|
||||
return waitForPaintsFlushed();
|
||||
}).then(() => {
|
||||
var transform =
|
||||
SpecialPowers.DOMWindowUtils.getOMTAStyle(div, 'transform');
|
||||
// (200px + 300px) * (50 * MS_PER_SEC / 100 * MS_PER_SEC) = 250px.
|
||||
assert_matrix_equals(transform, 'matrix(1, 0, 0, 1, 250, 0)',
|
||||
'Composed transform value should be composed onto the value of ' +
|
||||
'lower-priority animation with fill:forwards');
|
||||
});
|
||||
}, 'Transform value for animation with no keyframe at offset 0 at 50% when ' +
|
||||
'composed onto a underlying animation with fill:forwards');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
|
||||
var div = addDiv(t);
|
||||
var lowerAnimation =
|
||||
div.animate({ transform: [ 'translateX(100px)', 'translateX(200px)' ] },
|
||||
{ duration: 10 * MS_PER_SEC,
|
||||
endDelay: -5 * MS_PER_SEC,
|
||||
fill: 'forwards' });
|
||||
var higherAnimation = div.animate({ transform: 'translateX(300px)' },
|
||||
100 * MS_PER_SEC);
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(50 * MS_PER_SEC);
|
||||
|
||||
// We need to wait for a paint just like the above test.
|
||||
return waitForPaintsFlushed();
|
||||
}).then(() => {
|
||||
var transform =
|
||||
SpecialPowers.DOMWindowUtils.getOMTAStyle(div, 'transform');
|
||||
// (150px + 300px) * (50 * MS_PER_SEC / 100 * MS_PER_SEC) = 225px.
|
||||
assert_matrix_equals(transform, 'matrix(1, 0, 0, 1, 225, 0)',
|
||||
'Composed transform value should be composed onto the value of ' +
|
||||
'lower-priority animation with fill:forwards and negative endDelay');
|
||||
});
|
||||
}, 'Transform value for animation with no keyframe at offset 0 at 50% when ' +
|
||||
'composed onto a underlying animation with fill:forwards and negative ' +
|
||||
'endDelay');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
|
||||
var div = addDiv(t);
|
||||
var lowerAnimation =
|
||||
div.animate({ transform: [ 'translateX(100px)', 'translateX(200px)' ] },
|
||||
{ duration: 10 * MS_PER_SEC,
|
||||
endDelay: 100 * MS_PER_SEC,
|
||||
fill: 'forwards' });
|
||||
var higherAnimation = div.animate({ transform: 'translateX(300px)' },
|
||||
100 * MS_PER_SEC);
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(50 * MS_PER_SEC);
|
||||
|
||||
var transform =
|
||||
SpecialPowers.DOMWindowUtils.getOMTAStyle(div, 'transform');
|
||||
// (200px + 300px) * 0.5
|
||||
assert_matrix_equals(transform, 'matrix(1, 0, 0, 1, 250, 0)',
|
||||
'Composed transform value should be composed onto the value of ' +
|
||||
'lower-priority animation with fill:forwards during positive endDelay');
|
||||
});
|
||||
}, 'Transform value for animation with no keyframe at offset 0 at 50% when ' +
|
||||
'composed onto a underlying animation with fill:forwards during positive ' +
|
||||
'endDelay');
|
||||
|
||||
done();
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,15 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<script src='/resources/testharness.js'></script>
|
||||
<script src='/resources/testharnessreport.js'></script>
|
||||
<div id='log'></div>
|
||||
<script>
|
||||
'use strict';
|
||||
setup({explicit_done: true});
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{ 'set': [['dom.animations-api.core.enabled', true]] },
|
||||
function() {
|
||||
window.open('file_missing-keyframe-on-compositor.html');
|
||||
});
|
||||
</script>
|
||||
</html>
|
|
@ -29,6 +29,31 @@ function assert_times_equal(actual, expected, description) {
|
|||
assert_approx_equals(actual, expected, TIME_PRECISION, description);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compare matrix string like 'matrix(1, 0, 0, 1, 100, 0)'.
|
||||
* This function allows error, 0.01, because on Android when we are scaling down
|
||||
* the document, it results in some errors.
|
||||
*/
|
||||
function assert_matrix_equals(actual, expected, description) {
|
||||
var matrixRegExp = /^matrix\((.+),(.+),(.+),(.+),(.+),(.+)\)/;
|
||||
assert_regexp_match(actual, matrixRegExp,
|
||||
'Actual value should be a matrix')
|
||||
assert_regexp_match(expected, matrixRegExp,
|
||||
'Expected value should be a matrix');
|
||||
|
||||
var actualMatrixArray = actual.match(matrixRegExp).slice(1).map(Number);
|
||||
var expectedMatrixArray = expected.match(matrixRegExp).slice(1).map(Number);
|
||||
|
||||
assert_equals(actualMatrixArray.length, expectedMatrixArray.length,
|
||||
'Array lengths should be equal (got \'' + expected + '\' and \'' + actual +
|
||||
'\'): ' + description);
|
||||
for (var i = 0; i < actualMatrixArray.length; i++) {
|
||||
assert_approx_equals(actualMatrixArray[i], expectedMatrixArray[i], 0.01,
|
||||
'Matrix array should be equal (got \'' + expected + '\' and \'' + actual +
|
||||
'\'): ' + description);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a div to the document body and creates an animation on the div.
|
||||
* NOTE: This function asserts when trying to create animations with durations
|
||||
|
@ -173,7 +198,8 @@ if (opener) {
|
|||
"assert_between_inclusive",
|
||||
"assert_true", "assert_false",
|
||||
"assert_class_string", "assert_throws",
|
||||
"assert_unreached", "promise_test", "test"]) {
|
||||
"assert_unreached", "assert_regexp_match",
|
||||
"promise_test", "test"]) {
|
||||
window[funcName] = opener[funcName].bind(opener);
|
||||
}
|
||||
|
||||
|
@ -206,6 +232,29 @@ function setupSynchronousObserver(t, target, subtree) {
|
|||
return observer;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a promise that is resolved when the document has finished loading.
|
||||
*/
|
||||
function waitForDocumentLoad() {
|
||||
return new Promise(function(resolve, reject) {
|
||||
if (document.readyState === "complete") {
|
||||
resolve();
|
||||
} else {
|
||||
window.addEventListener("load", resolve);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* Enters test refresh mode, and restores the mode when |t| finishes.
|
||||
*/
|
||||
function useTestRefreshMode(t) {
|
||||
SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(0);
|
||||
t.add_cleanup(() => {
|
||||
SpecialPowers.DOMWindowUtils.restoreNormalRefresh();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if off-main-thread animations.
|
||||
*/
|
||||
|
|
Загрузка…
Ссылка в новой задаче