100 lines
2.9 KiB
HTML
100 lines
2.9 KiB
HTML
<!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() {
|
|
// 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>
|