diff options
Diffstat (limited to '')
-rw-r--r-- | dom/media/test/test_periodic_timeupdate.html | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/dom/media/test/test_periodic_timeupdate.html b/dom/media/test/test_periodic_timeupdate.html new file mode 100644 index 0000000000..5d40c7e38a --- /dev/null +++ b/dom/media/test/test_periodic_timeupdate.html @@ -0,0 +1,100 @@ +<!DOCTYPE HTML> +<html> +<head> +<title>Periodic timeupdate test</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +<script type="application/javascript"> + +/** + * To ensure that when dispatching periodic `timeupdate` event, we would only + * dispatch that once within 250ms according to the spec. This test would end + * after receiving certain number of timeupdate` event. + */ +const sNumPeriodicTimeupdatesToEndTestAfter = 5; +const sTimeThreshold = 250; + +add_task(async function testPeriodicTimeupdateShouldOnlyBeDispatchedOnceWithin250Ms() { + const video = document.createElement('video'); + video.src = "gizmo.mp4"; + video.loop = true; + video._timeupdateCount = 0; + document.body.appendChild(video); + ok(await video.play().then(_=>true,_=>false), "video started playing"); + const culprit = createCulpritToMakeMainThreadBusy(); + await new Promise(r => { + function endTest() { + video.removeEventListener("timeupdate", checkTimeupdate); + culprit.shutdown(); + r(); + } + video.onseeking = () => { + info(`seeking starts (looping back to the head)`); + video._ignoreEvents = true; + } + video.onseeked = () => { + info(`seeking ends`); + video._ignoreEvents = false; + } + function checkTimeupdate(event) { + // When reaching to the end, video would perform a seek to the start + // position where one mandatory `timeupdate` would be dispatched. + if (video._ignoreEvents) { + info(`ignore non-periodic timeupdate because that is allowed to be dispatched within ${sTimeThreshold}ms`); + return; + } + + const now = performance.now(); + if (video._prevTime === undefined) { + info(`recevied the first 'timeupdate'`); + video._prevTime = now; + return; + } + + const timeDiff = now - video._prevTime; + if (timeDiff < sTimeThreshold) { + ok(false, `Time diff ${timeDiff} is smaller than ${sTimeThreshold}ms!`); + endTest(); + return; + } + + ok(true, `Time diff ${timeDiff} since last time received 'timeupdate'`); + video._prevTime = now; + info(`check timeupdate ${++video._timeupdateCount} time`); + if (video._timeupdateCount == sNumPeriodicTimeupdatesToEndTestAfter) { + endTest(); + } + }; + video.addEventListener("timeupdate", checkTimeupdate); + }); +}); + +window.onmessage = _ => blockMainThreadForMilliseconds(1); + +/** + * Following are helper functions + */ +function blockMainThreadForMilliseconds(ms) { + const lastTime = performance.now(); + while (lastTime + ms > performance.now()); +} + +function createCulpritToMakeMainThreadBusy() { + let culprit = {}; + culprit._id = setInterval(_ => { + blockMainThreadForMilliseconds(1000); + }, 0); + culprit.shutdown = _ => { + clearInterval(culprit._id); + } + for (let i = 0; i < 5000; ++i) { + window.postMessage("foo", "*"); + } + return culprit; +} + +</script> +</head> +<body> +</body> +</html> |