| Index: third_party/WebKit/LayoutTests/http/tests/media/video-play-stall.html
|
| diff --git a/third_party/WebKit/LayoutTests/http/tests/media/video-play-stall.html b/third_party/WebKit/LayoutTests/http/tests/media/video-play-stall.html
|
| index 7f6a9a103fb607745478c9040d5e244e77f00723..0e99c95e121e08398605b5734cc246fd24fcdab8 100644
|
| --- a/third_party/WebKit/LayoutTests/http/tests/media/video-play-stall.html
|
| +++ b/third_party/WebKit/LayoutTests/http/tests/media/video-play-stall.html
|
| @@ -1,43 +1,114 @@
|
| -<video></video>
|
| -<p>Test that stalled, timeupdate and waiting events are sent when media load stalls in the middle.</p>
|
| +<!DOCTYPE html>
|
| +<title>Test that stalled, timeupdate and waiting events are sent when media load stalls in the middle.</title>
|
| +<video id="test_video"></video>
|
| +<div id="log_console"></div>
|
| <script src=../../media-resources/media-file.js></script>
|
| -<!-- TODO(foolip): Convert test to testharness.js. crbug.com/588956
|
| - (Please avoid writing new tests using video-test.js) -->
|
| -<script src=../../media-resources/video-test.js></script>
|
| +<script src="/w3c/resources/testharness.js"></script>
|
| +<script src="/w3c/resources/testharnessreport.js"></script>
|
| <script>
|
| +async_test(t => {
|
| + let video = document.getElementById('test_video');
|
| + let log_console = document.getElementById('log_console');
|
|
|
| - var timeupdateCount = 0;
|
| - var waitingCount = 0;
|
| + // For debugging.
|
| + function logEvent(e) {
|
| + let span = document.createElement("span");
|
| + span.innerHTML = 'event: ' + e.type + '<br>';
|
| + log_console.appendChild(span);
|
| + };
|
|
|
| - waitForEvent('durationchange');
|
| - waitForEvent('loadedmetadata');
|
| - waitForEvent('loadeddata');
|
| - waitForEvent('canplaythrough');
|
| - waitForEvent('canplay', function () {
|
| + playback_ew = new EventWatcher(t, video, [
|
| + 'canplay',
|
| + 'canplaythrough',
|
| + 'durationchange',
|
| + 'loadedmetadata',
|
| + 'loadeddata',
|
| + 'play',
|
| + 'playing',
|
| + 'waiting']);
|
|
|
| - mediaElement.addEventListener('timeupdate', function () {
|
| - // timeupdate events are fired as playback progresses so only verify that at least one
|
| - // event is fired
|
| - ++timeupdateCount;
|
| - if (timeupdateCount == 1)
|
| - consoleWrite("EVENT(timeupdate)");
|
| - } );
|
| + // The stalled event needs a separate watcher as it can be fired at any
|
| + // point during the sequence of other playback events. Stalled is triggered
|
| + // by prolonged network inactivity.
|
| + stalled_ew = new EventWatcher(t, video, [
|
| + 'stalled']);
|
|
|
| - waitForEvent('waiting', function () {
|
| - ++waitingCount;
|
| - if (waitingCount > 1)
|
| - failTest("too many 'waiting' events fired.");
|
| + // This helper is an alternative to EventWatcher for events that fire on a
|
| + // recurring basis. EventWatcher is not suitable because you must always be
|
| + // "waiting" for the event to fire every time, whereas this method allows
|
| + // you to just verify that it fired once and move on.
|
| + function waitForRecurringEvent(name) {
|
| + let resolve_cb;
|
| + let promise = new Promise(function(resolve, reject) {
|
| + resolve_cb = resolve;
|
| + });
|
| + video.addEventListener(name, t.step_func((evt) => resolve_cb(evt)));
|
| + return promise;
|
| + }
|
|
|
| - waitForEvent('timeupdate');
|
| - } );
|
| + // NOTE: Event sequence verification is achieved by chaining together
|
| + // promises via then(). To verify separate parallel event sequences (e.g.
|
| + // playback vs network), we setup separate chains of promises. Promise.all
|
| + // ensures that all separate sequences complete.
|
| +
|
| + // Verify playback progresses then runs out of data.
|
| + Promise.all([
|
| + // First wait for the resource to load.
|
| + playback_ew.wait_for('durationchange').then(logEvent)
|
| + .then(() => playback_ew.wait_for('loadedmetadata')).then(logEvent)
|
| + .then(() => playback_ew.wait_for('loadeddata')).then(logEvent)
|
| + .then(() => playback_ew.wait_for('canplay')).then(logEvent)
|
| + .then(() => playback_ew.wait_for('canplaythrough')).then(logEvent)
|
| + .then(t.step_func(function() {
|
| + assert_true(video.readyState > HTMLMediaElement.HAVE_CURRENT_DATA);
|
| + }))
|
| + // Now play the file and wait for playback to stall (fire waiting).
|
| + .then(t.step_func(function() {
|
| + video.play();
|
| + // NOTE: setting the wait_for here because we will miss it if we do
|
| + // it after the play call resolves its promise.
|
| + return playback_ew.wait_for('play').then(logEvent);
|
| + }))
|
| + .then(() => playback_ew.wait_for('playing')).then(logEvent)
|
| + // Now observe waiting event and verify readyState
|
| + .then(() => playback_ew.wait_for('waiting')).then(logEvent)
|
| + .then(t.step_func(function(){
|
| + assert_equals(HTMLMediaElement.HAVE_CURRENT_DATA, video.readyState);
|
| + })),
|
| +
|
| + // timeupdate should fire throughout playback. Make sure we see one.
|
| + waitForRecurringEvent('timeupdate').then(logEvent),
|
| +
|
| + // progress should fire throughout download. Make sure we see one.
|
| + // Later the download should stall.
|
| + waitForRecurringEvent('progress').then(logEvent)
|
| + .then(() => stalled_ew.wait_for('stalled')).then(logEvent)
|
| +
|
| + // Verify download and playback resume.
|
| + ]).then(() => Promise.all([
|
| + // Playback should resume when download again makes progress.
|
| + waitForRecurringEvent('progress').then(logEvent),
|
| +
|
| + // timeupdate should fire throughout playback. Make sure we see one.
|
| + waitForRecurringEvent('timeupdate').then(logEvent),
|
| +
|
| + // Verify correct sequence of playback events.
|
| + playback_ew.wait_for('canplay').then(logEvent)
|
| + .then(t.step_func(function() {
|
| + assert_true(video.readyState > HTMLMediaElement.HAVE_CURRENT_DATA);
|
| + }))
|
| + .then(() => playback_ew.wait_for('playing')).then(logEvent)
|
| + .then(() => playback_ew.wait_for('canplaythrough')).then(logEvent)
|
| + ])).then(t.step_func_done());
|
|
|
| - waitForEventAndEnd('stalled');
|
| - } );
|
|
|
| // Find a supported media file.
|
| var mediaFile = findMediaFile("video", "content/test");
|
| var mimeType = mimeTypeForFile(mediaFile);
|
| + // URL will load part of the file, pause for 8 seconds, then load the rest.
|
| + // The delay of 8 seconds is chosen to reduce flakiness in waiting for the
|
| + // stalled event, which should arrive after roughly 3 seconds of inactivity.
|
| + video.src = "http://127.0.0.1:8000/resources/load-and-stall.cgi?name=../../../media/" + mediaFile + "&mimeType=" + mimeType + "&stallAt=100000&stallFor=8";
|
|
|
| - video.src = "http://127.0.0.1:8000/resources/load-and-stall.cgi?name=../../../media/" + mediaFile + "&mimeType=" + mimeType + "&stallAt=100000&stallFor=6";
|
| - run("video.play()");
|
| +}, "Stalled download pauses playback. When download resumes playback continues. Verify events and readyStates.");
|
| </script>
|
|
|