Source code

Revision control

Other Tools

Test Info: Warnings

  • This test gets skipped with pattern: (os == "win" && processor == "aarch64")
<!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>