summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/scroll-animations/view-timelines/testcommon.js
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/scroll-animations/view-timelines/testcommon.js')
-rw-r--r--testing/web-platform/tests/scroll-animations/view-timelines/testcommon.js145
1 files changed, 145 insertions, 0 deletions
diff --git a/testing/web-platform/tests/scroll-animations/view-timelines/testcommon.js b/testing/web-platform/tests/scroll-animations/view-timelines/testcommon.js
new file mode 100644
index 0000000000..65301215c4
--- /dev/null
+++ b/testing/web-platform/tests/scroll-animations/view-timelines/testcommon.js
@@ -0,0 +1,145 @@
+'use strict';
+
+function assert_px_equals(observed, expected, description) {
+ assert_equals(observed.unit, 'px',
+ `Unexpected unit type for '${description}'`);
+ assert_approx_equals(observed.value, expected, 0.0001,
+ `Unexpected value for ${description}`);
+}
+
+function CreateViewTimelineOpacityAnimation(test, target, options) {
+ const timeline_options = {
+ subject: target,
+ axis: 'block'
+ };
+ if (options && 'timeline' in options) {
+ for (let key in options.timeline) {
+ timeline_options[key] = options.timeline[key];
+ }
+ }
+ const animation_options = {
+ timeline: new ViewTimeline(timeline_options)
+ };
+ if (options && 'animation' in options) {
+ for (let key in options.animation) {
+ animation_options[key] = options.animation[key];
+ }
+ }
+
+ const anim =
+ target.animate({ opacity: [0.3, 0.7] }, animation_options);
+ test.add_cleanup(() => {
+ anim.cancel();
+ });
+ return anim;
+}
+
+// Verify that range specified in the options aligns with the active range of
+// the animation.
+//
+// Sample call:
+// await runTimelineBoundsTest(t, {
+// timeline: { inset: [ CSS.percent(0), CSS.percent(20)] },
+// timing: { fill: 'both' }
+// startOffset: 600,
+// endOffset: 900
+// });
+async function runTimelineBoundsTest(t, options, message) {
+ container.scrollLeft = 0;
+ await waitForNextFrame();
+
+ const anim =
+ options.anim ||
+ CreateViewTimelineOpacityAnimation(t, target, options);
+ if (options.timing)
+ anim.effect.updateTiming(options.timing);
+
+ const timeline = anim.timeline;
+ await anim.ready;
+
+ // Advance to the start offset, which triggers entry to the active phase.
+ container.scrollLeft = options.startOffset;
+ await waitForNextFrame();
+ assert_equals(getComputedStyle(target).opacity, '0.3',
+ `Effect at the start of the active phase: ${message}`);
+
+ // Advance to the midpoint of the animation.
+ container.scrollLeft = (options.startOffset + options.endOffset) / 2;
+ await waitForNextFrame();
+ assert_equals(getComputedStyle(target).opacity,'0.5',
+ `Effect at the midpoint of the active range: ${message}`);
+
+ // Advance to the end of the animation.
+ container.scrollLeft = options.endOffset;
+ await waitForNextFrame();
+ assert_equals(getComputedStyle(target).opacity, '0.7',
+ `Effect is in the active phase at effect end time: ${message}`);
+
+ // Return the animation so that we can continue testing with the same object.
+ return anim;
+}
+
+// Sets the start and end range for a view timeline and ensures that the
+// range aligns with expected values.
+//
+// Sample call:
+// await runTimelineRangeTest(t, {
+// rangeStart: { rangeName: 'cover', offset: CSS.percent(0) } ,
+// rangeEnd: { rangeName: 'cover', offset: CSS.percent(100) },
+// startOffset: 600,
+// endOffset: 900
+// });
+async function runTimelineRangeTest(t, options) {
+ const rangeToString = range => {
+ const parts = [];
+ if (range.rangeName)
+ parts.push(range.rangeName);
+ if (range.offset)
+ parts.push(`${range.offset.value}%`);
+ return parts.join(' ');
+ };
+ const range =
+ `${rangeToString(options.rangeStart)} to ` +
+ `${rangeToString(options.rangeEnd)}`;
+
+ options.timeline = {
+ axis: 'inline'
+ };
+ options.animation = {
+ rangeStart: options.rangeStart,
+ rangeEnd: options.rangeEnd,
+ };
+ options.timing = {
+ // Set fill to accommodate floating point precision errors at the
+ // endpoints.
+ fill: 'both'
+ };
+
+ return runTimelineBoundsTest(t, options, range);
+}
+
+// Sets the Inset for a view timeline and ensures that the range aligns with
+// expected values.
+//
+// Sample call:
+// await runTimelineInsetTest(t, {
+// inset: [ CSS.px(20), CSS.px(40) ]
+// startOffset: 600,
+// endOffset: 900
+// });
+async function runTimelineInsetTest(t, options) {
+ options.timeline = {
+ axis: 'inline',
+ inset: options.inset
+ };
+ options.timing = {
+ // Set fill to accommodate floating point precision errors at the
+ // endpoints.
+ fill: 'both'
+ }
+ const length = options.inset.length;
+ const range =
+ (options.inset instanceof Array) ? options.inset.join(' ')
+ : options.inset;
+ return runTimelineBoundsTest(t, options, range);
+}