| <!DOCTYPE html> |
| <html> |
| <title>Test the basics of the video.requestVideoFrameCallback() API.</title> |
| <body></body> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <script src="/common/media.js"></script> |
| <script> |
| var testVideo = { |
| url: getVideoURI('/media/movie_5'), |
| height: 240, |
| width: 320, |
| } |
| |
| var altTestVideo = { |
| url: getVideoURI('/media/counting'), |
| height: 240, |
| width: 320, |
| } |
| |
| promise_test(async function(t) { |
| let done; |
| const promise = new Promise(resolve => done = resolve); |
| |
| let video = document.createElement('video'); |
| document.body.appendChild(video); |
| |
| let id = video.requestVideoFrameCallback( |
| t.step_func((time, metadata) => { |
| assert_true(time > 0); |
| assert_equals(metadata.height, testVideo.height); |
| assert_equals(metadata.width, testVideo.width); |
| done(); |
| }) |
| ); |
| |
| assert_true(id > 0); |
| |
| video.src = testVideo.url; |
| await video.play(); |
| |
| return promise; |
| }, 'Test we can register a video.rVFC callback.'); |
| |
| promise_test(async function(t) { |
| let done; |
| const promise = new Promise(resolve => done = resolve); |
| |
| let video = document.createElement('video'); |
| document.body.appendChild(video); |
| |
| video.requestVideoFrameCallback( |
| t.step_func(video_now => { |
| // Queue a call to window.rAF, and make sure it is executed within the |
| // same turn of the event loop (with the same 'time' parameter). |
| window.requestAnimationFrame( t.step_func( window_now => { |
| assert_equals(video_now, window_now); |
| done(); |
| })); |
| }) |
| ); |
| |
| video.src = testVideo.url; |
| await video.play(); |
| |
| return promise; |
| }, 'Test video.rVFC callbacks run before window.rAF callbacks.'); |
| |
| |
| promise_test(async function(t) { |
| let done; |
| const promise = new Promise(resolve => done = resolve); |
| |
| let video = document.createElement('video'); |
| document.body.appendChild(video); |
| |
| let id = video.requestVideoFrameCallback( |
| t.step_func(_ => { |
| assert_unreached("Cancelled callbacks shouldn't be executed") |
| }) |
| ); |
| |
| video.cancelVideoFrameCallback(id); |
| |
| video.requestVideoFrameCallback( |
| t.step_func(_ => { |
| // At this point, the other callback shouldn't have fired, but |
| // give it some more time and really make sure it doesn't, by going |
| // throught the event loop once more. |
| t.step_timeout(() => { done(); }, 0); |
| }) |
| ); |
| |
| video.src = testVideo.url; |
| await video.play(); |
| |
| return promise; |
| }, 'Test we can cancel a video.rVFC request.'); |
| |
| test(function(t) { |
| let video = document.createElement('video'); |
| document.body.appendChild(video); |
| |
| // requestVideoFrameCallback() expects 1 function as a parameter. |
| assert_throws_js(TypeError, _ => { video.requestVideoFrameCallback() } ); |
| assert_throws_js(TypeError, _ => { video.requestVideoFrameCallback(0) }); |
| assert_throws_js(TypeError, _ => { video.requestVideoFrameCallback("foo") }); |
| |
| // cancelVideoFrameCallback() expects 1 number as a parameter |
| assert_throws_js(TypeError, _ => { video.cancelVideoFrameCallback() } ); |
| |
| // Invalid calls are just no-ops |
| video.cancelVideoFrameCallback(_ => {}); |
| video.cancelVideoFrameCallback(NaN); |
| video.cancelVideoFrameCallback("foo"); |
| video.cancelVideoFrameCallback(12345); |
| video.cancelVideoFrameCallback(-1); |
| |
| }, 'Test invalid calls to the video.rVFC API.'); |
| |
| promise_test(async function(t) { |
| let video = document.createElement('video'); |
| video.autoplay = true; |
| document.body.appendChild(video); |
| |
| let first_width = 0; |
| let first_height = 0; |
| |
| video.src = testVideo.url; |
| |
| await video.play(); |
| |
| // Switch to and from a second video, and make sure we get rVFC calls at |
| // each step. |
| return new Promise((resolve, reject) => { |
| let onReturnToOriginalVideo = t.step_func((now, metadata) => { |
| assert_equals(first_width, metadata.width); |
| assert_equals(first_height, metadata.height); |
| |
| resolve(); |
| }); |
| |
| let onAltVideoFirstFrame = t.step_func((now, metadata) => { |
| // The videos have different sizes, and shouldn't match. |
| assert_not_equals(first_width, metadata.width); |
| assert_not_equals(first_height, metadata.height); |
| |
| // Swith back to the original video. |
| video.requestVideoFrameCallback(onReturnToOriginalVideo); |
| video.src = testVideo.url; |
| }); |
| |
| let onFirstFrame = t.step_func((now, metadata) => { |
| first_width = metadata.width; |
| first_height = metadata.height; |
| |
| // Callbacks should persist after changing the source to the alt video. |
| video.requestVideoFrameCallback(onAltVideoFirstFrame); |
| video.src = altTestVideo.url; |
| }) |
| |
| video.requestVideoFrameCallback(onFirstFrame); |
| }); |
| }, 'Test video.rVFC does not stop when switching sources.'); |
| |
| </script> |
| </html> |