diff --git a/layout/generic/test/test_scroll_behavior.html b/layout/generic/test/test_scroll_behavior.html index 52623c7584d3..4fd9eefde1a3 100644 --- a/layout/generic/test/test_scroll_behavior.html +++ b/layout/generic/test/test_scroll_behavior.html @@ -35,59 +35,55 @@ SpecialPowers.pushPrefEnv( { 'set': [['layout.css.scroll-behavior.enabled', true]] }, - function () { - testScrollBehaviorInterruption(function() { - testScrollBehaviorFramerate(function() { - window.scrollTo(0,0); - SimpleTest.finish(); - }); - }); + async function () { + await testScrollBehaviorInterruption(); + await testScrollBehaviorFramerate(); + window.scrollTo(0,0); + SimpleTest.finish(); } ); }); - - function testScrollBehaviorInterruption(nextTest) { + async function testScrollBehaviorInterruption() { // Take control of refresh driver SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(0); - waitForApzFlushedRepaints(function() { + await promiseApzFlushedRepaints(); - window.scrollTo(10, 9); - ok(window.scrollX == 10 && window.scrollY == 9, - "instant scroll-behavior must be synchronous when setting initial position"); + window.scrollTo(10, 9); + ok(window.scrollX == 10 && window.scrollY == 9, + "instant scroll-behavior must be synchronous when setting initial position"); - window.scrollTo(15, 16); - ok(window.scrollX == 15 && window.scrollY == 16, - "instant scroll-behavior must be synchronous when setting new position"); + window.scrollTo(15, 16); + ok(window.scrollX == 15 && window.scrollY == 16, + "instant scroll-behavior must be synchronous when setting new position"); - window.scrollTo({left: 100, top: 200, behavior: 'smooth'}); - ok(window.scrollX == 15 && window.scrollY == 16, - "smooth scroll-behavior must be asynchronous"); + window.scrollTo({left: 100, top: 200, behavior: 'smooth'}); + ok(window.scrollX == 15 && window.scrollY == 16, + "smooth scroll-behavior must be asynchronous"); - SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(100); - waitForApzFlushedRepaints(function() { - ok(window.scrollX != 15 && window.scrollY != 16 - && window.scrollX != 100 && window.scrollY != 200, - "smooth scroll-behavior must be triggered by window.scrollTo"); + SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(100); + await promiseApzFlushedRepaints(); - window.scrollTo(50, 52); - ok(window.scrollX == 50 && window.scrollY == 52, - "instant scroll-behavior must interrupt smooth scroll-behavior animation"); + ok(window.scrollX != 15 && window.scrollY != 16 + && window.scrollX != 100 && window.scrollY != 200, + "smooth scroll-behavior must be triggered by window.scrollTo"); - SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(100); - waitForApzFlushedRepaints(function() { - ok(window.scrollX == 50 && window.scrollY == 52, - "smooth scroll-behavior animation must stop after being interrupted"); + window.scrollTo(50, 52); + ok(window.scrollX == 50 && window.scrollY == 52, + "instant scroll-behavior must interrupt smooth scroll-behavior animation"); - // Release control of refresh driver - SpecialPowers.DOMWindowUtils.restoreNormalRefresh(); - waitForApzFlushedRepaints(nextTest); - }); - }); - }); + SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(100); + await promiseApzFlushedRepaints(); + + ok(window.scrollX == 50 && window.scrollY == 52, + "smooth scroll-behavior animation must stop after being interrupted"); + + // Release control of refresh driver + SpecialPowers.DOMWindowUtils.restoreNormalRefresh(); + await promiseApzFlushedRepaints(); } - function testScrollBehaviorFramerate(nextTest) { + async function testScrollBehaviorFramerate() { /** * CSSOM-View scroll-behavior smooth scroll animations must produce the * same results indendently of frame-rate: @@ -116,16 +112,9 @@ {x: 1, y: 100}, {x: -100, y: 50000} ]; - var deltaIndex = 0; - - function testDeltas() { - if(deltaIndex >= deltas.length) { - nextTest(); - return; - } + for (var deltaIndex = 0; deltaIndex < deltas.length; deltaIndex++) { var deltaX = deltas[deltaIndex].x; var deltaY = deltas[deltaIndex].y; - deltaIndex++; // startX and startY must be at least as big as the greatest negative // number in the deltas array in order to prevent the animation from @@ -136,91 +125,79 @@ var endY = startY + deltaY; var referenceTimeStep = Math.floor(1000 / referenceFrameRate); - sampleAnimation(startX, startY, endX, endY, - referenceTimeStep, function(refSamples) { + let refSamples = await sampleAnimation(startX, startY, endX, endY, + referenceTimeStep); - var referenceDuration = refSamples.length * referenceTimeStep; // ms + var referenceDuration = refSamples.length * referenceTimeStep; // ms - var frameRateIndex=0; + for (var frameRateIndex = 0; frameRateIndex < frameRates.length; frameRateIndex++) { + var frameRate = frameRates[frameRateIndex]; - function testFrameRate() { - if(frameRateIndex < frameRates.length) { - var frameRate = frameRates[frameRateIndex++]; - var testTimeStep = Math.floor(1000 / frameRate); + var testTimeStep = Math.floor(1000 / frameRate); - sampleAnimation(startX, startY, endX, endY, - testTimeStep, function(testSamples) { - var testDuration = testSamples.length * testTimeStep; // ms + let testSamples = await sampleAnimation(startX, startY, endX, endY, + testTimeStep); + var testDuration = testSamples.length * testTimeStep; // ms - // Variance in duration of animation must be accurate to within one - // frame interval - var durationVariance = Math.max(0, Math.abs(testDuration - referenceDuration) - testTimeStep); - is(durationVariance, 0, 'Smooth scroll animation duration must not ' - + 'be framerate dependent at deltaX: ' + deltaX + ', deltaY: ' - + deltaY + ', frameRate: ' + frameRate + 'fps'); + // Variance in duration of animation must be accurate to within one + // frame interval + var durationVariance = Math.max(0, Math.abs(testDuration - referenceDuration) - testTimeStep); + is(durationVariance, 0, 'Smooth scroll animation duration must not ' + + 'be framerate dependent at deltaX: ' + deltaX + ', deltaY: ' + + deltaY + ', frameRate: ' + frameRate + 'fps'); - var maxVariance = 0; - testSamples.forEach(function(sample, sampleIndex) { + var maxVariance = 0; + testSamples.forEach(function(sample, sampleIndex) { - var testToRef = refSamples.length / testSamples.length; - var refIndexThisFrame = clamp(Math.floor(sampleIndex * testToRef), - 0, refSamples.length - 1); - var refIndexPrevFrame = clamp(Math.floor((sampleIndex - 1) * testToRef), - 0, refSamples.length - 1); - var refIndexNextFrame = clamp(Math.floor((sampleIndex + 1) * testToRef), - 0, refSamples.length - 1); + var testToRef = refSamples.length / testSamples.length; + var refIndexThisFrame = clamp(Math.floor(sampleIndex * testToRef), + 0, refSamples.length - 1); + var refIndexPrevFrame = clamp(Math.floor((sampleIndex - 1) * testToRef), + 0, refSamples.length - 1); + var refIndexNextFrame = clamp(Math.floor((sampleIndex + 1) * testToRef), + 0, refSamples.length - 1); - var refSampleThisFrame = refSamples[refIndexThisFrame]; - var refSamplePrevFrame = refSamples[refIndexPrevFrame]; - var refSampleNextFrame = refSamples[refIndexNextFrame]; + var refSampleThisFrame = refSamples[refIndexThisFrame]; + var refSamplePrevFrame = refSamples[refIndexPrevFrame]; + var refSampleNextFrame = refSamples[refIndexNextFrame]; - var refXMin = Math.min(refSamplePrevFrame[0], - refSampleThisFrame[0], - refSampleNextFrame[0]); + var refXMin = Math.min(refSamplePrevFrame[0], + refSampleThisFrame[0], + refSampleNextFrame[0]); - var refYMin = Math.min(refSamplePrevFrame[1], - refSampleThisFrame[1], - refSampleNextFrame[1]); + var refYMin = Math.min(refSamplePrevFrame[1], + refSampleThisFrame[1], + refSampleNextFrame[1]); - var refXMax = Math.max(refSamplePrevFrame[0], - refSampleThisFrame[0], - refSampleNextFrame[0]); + var refXMax = Math.max(refSamplePrevFrame[0], + refSampleThisFrame[0], + refSampleNextFrame[0]); - var refYMax = Math.max(refSamplePrevFrame[1], - refSampleThisFrame[1], - refSampleNextFrame[1]); + var refYMax = Math.max(refSamplePrevFrame[1], + refSampleThisFrame[1], + refSampleNextFrame[1]); - // Varience is expected to be at most 1 pixel beyond the range, - // due to integer rounding of pixel position. - var positionTolerance = 1; // 1 pixel + // Varience is expected to be at most 1 pixel beyond the range, + // due to integer rounding of pixel position. + var positionTolerance = 1; // 1 pixel - maxVariance = Math.max(maxVariance, - refXMin - sample[0] - positionTolerance, - sample[0] - refXMax - positionTolerance, - refYMin - sample[1] - positionTolerance, - sample[1] - refYMax - positionTolerance); - }); + maxVariance = Math.max(maxVariance, + refXMin - sample[0] - positionTolerance, + sample[0] - refXMax - positionTolerance, + refYMin - sample[1] - positionTolerance, + sample[1] - refYMax - positionTolerance); + }); - is(maxVariance, 0, 'Smooth scroll animated position must not be ' - + 'framerate dependent at deltaX: ' + deltaX + ', deltaY: ' - + deltaY + ', frameRate: ' + frameRate + 'fps'); - testFrameRate(); - }); - } else { - waitForApzFlushedRepaints(testDeltas); - } - } + is(maxVariance, 0, 'Smooth scroll animated position must not be ' + + 'framerate dependent at deltaX: ' + deltaX + ', deltaY: ' + + deltaY + ', frameRate: ' + frameRate + 'fps'); + } - testFrameRate(); - - }); + await promiseApzFlushedRepaints(); } - - testDeltas(); - } - function sampleAnimation(startX, startY, endX, endY, timeStep, callback) { + async function sampleAnimation(startX, startY, endX, endY, timeStep) { // The animation must be stopped at the destination position for // minStoppedFrames consecutive frames to detect that the animation has // completed. @@ -237,57 +214,45 @@ // Take control of refresh driver so we can synthesize // various frame rates SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(0); - waitForApzFlushedRepaints(function() { + await promiseApzFlushedRepaints(); - window.scrollTo(startX, startY); - window.scrollTo({left: endX, top: endY, behavior: 'smooth'}); + window.scrollTo(startX, startY); + window.scrollTo({left: endX, top: endY, behavior: 'smooth'}); - var currentTime = 0; // ms + var currentTime = 0; // ms - function advanceTime() { - if(currentTime < maxTime && frameCountAtDestination < 15) { + while (currentTime < maxTime && frameCountAtDestination < 15) { + positionSamples.push([window.scrollX, window.scrollY]); - positionSamples.push([window.scrollX, window.scrollY]); - - currentTime += timeStep; - SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(timeStep); - waitForApzFlushedRepaints(function() { - if (window.scrollX == endX && window.scrollY == endY) { - frameCountAtDestination++; - } else { - frameCountAtDestination = 0; - } - - advanceTime(); - }); - - } else { - isnot(frameCountAtDestination, 0, - 'Smooth scrolls must always end at their destination ' - + 'unless they are interrupted, at deltaX: ' - + (endX - startX) + ', deltaY: ' + (endY - startY)); - - window.scrollTo(0, 0); - - // Release control of refresh driver - SpecialPowers.DOMWindowUtils.restoreNormalRefresh(); - - waitForApzFlushedRepaints(function() { - - // We must not include the duplicated frames at the animation - // destination as the tests are dependant on the total duration of - // the animation to be accurate. - positionSamples.splice(1 - minStoppedFrames, - minStoppedFrames - 1); - - callback(positionSamples); - }); - } + currentTime += timeStep; + SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(timeStep); + await promiseApzFlushedRepaints(); + if (window.scrollX == endX && window.scrollY == endY) { + frameCountAtDestination++; + } else { + frameCountAtDestination = 0; } + } - advanceTime(); + isnot(frameCountAtDestination, 0, + 'Smooth scrolls must always end at their destination ' + + 'unless they are interrupted, at deltaX: ' + + (endX - startX) + ', deltaY: ' + (endY - startY)); - }); + window.scrollTo(0, 0); + + // Release control of refresh driver + SpecialPowers.DOMWindowUtils.restoreNormalRefresh(); + + await promiseApzFlushedRepaints(); + + // We must not include the duplicated frames at the animation + // destination as the tests are dependant on the total duration of + // the animation to be accurate. + positionSamples.splice(1 - minStoppedFrames, + minStoppedFrames - 1); + + return positionSamples; }