Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1332)

Unified Diff: third_party/WebKit/LayoutTests/http/tests/media/video-play-stall.html

Issue 2115143002: Transition media element to HAVE_CURRENT_DATA upon underflow. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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..cbabed9d297c8f14b63eaf6a1b76979893c75b82 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,115 @@
-<video></video>
+<video id="test_video"></video>
wolenetz 2016/07/07 21:32:03 {linux,win}_chromium_rel_ng bots didn't pass this
chcunningham 2016/07/07 22:29:41 The failure is: 17:12:24.365 252 worker/0 http/te
chcunningham 2016/07/12 00:47:17 I've changed the console.log calls to instead log
wolenetz 2016/07/13 22:27:54 Acknowledged.
<p>Test that stalled, timeupdate and waiting events are sent when media load stalls in the middle.</p>
<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 => {
wolenetz 2016/07/07 21:32:03 nit: left justify 0-margin the outermost portion o
wolenetz 2016/07/07 21:32:03 nit: is the => {... consistent with other tests? W
chcunningham 2016/07/12 00:47:17 Done.
chcunningham 2016/07/12 00:47:18 I think you mean async_test(function(t) { ... }).
wolenetz 2016/07/13 22:27:54 Acknowledged.
+ let video = document.getElementById('test_video');
- var timeupdateCount = 0;
- var waitingCount = 0;
+ // For debugging.
+ function logEvent(e) { console.log('event fired:' + e.type); };
- waitForEvent('durationchange');
- waitForEvent('loadedmetadata');
- waitForEvent('loadeddata');
- waitForEvent('canplaythrough');
- waitForEvent('canplay', function () {
+ let ReadyState = {
wolenetz 2016/07/07 21:32:03 These are already exposed on the IDL for HTMLMedia
chcunningham 2016/07/12 00:47:18 Duh! Done.
+ HAVE_NOTHING: 0,
+ HAVE_METADATA: 1,
+ HAVE_CURRENT_DATA: 2,
+ HAVE_FUTURE_DATA: 3,
+ HAVE_ENOUGH_DATA: 4
+ }
- 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)");
- } );
+ playback_ew = new EventWatcher(t, video, [
+ 'canplay',
+ 'canplaythrough',
+ 'durationchange',
+ 'loadedmetadata',
+ 'loadeddata',
+ 'play',
+ 'playing',
+ 'waiting']);
- waitForEvent('waiting', function () {
- ++waitingCount;
- if (waitingCount > 1)
- failTest("too many 'waiting' events fired.");
+ // 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('timeupdate');
- } );
+ // 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;
+ }
- waitForEventAndEnd('stalled');
- } );
+ // 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.
- // Find a supported media file.
- var mediaFile = findMediaFile("video", "content/test");
- var mimeType = mimeTypeForFile(mediaFile);
+ // Verify playback progress 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 > ReadyState.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(ReadyState.HAVE_CURRENT_DATA, video.readyState);
+ })),
- 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()");
+ // 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 > ReadyState.HAVE_CURRENT_DATA);
+ }))
+ .then(() => playback_ew.wait_for('playing')).then(logEvent)
+ .then(() => playback_ew.wait_for('canplaythrough')).then(logEvent)
+ ])).then(t.step_func_done());
+
+
+ // Find a supported media file.
+ var mediaFile = findMediaFile("video", "content/test");
+ var mimeType = mimeTypeForFile(mediaFile);
+ // URL will load part of the file, pause for 6 seconds, then load the rest.
+ // The delay of 6 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=6";
+
+ }, "Stalled download pauses playback. When download resumes playback continues. Verify events and readyStates.");
</script>

Powered by Google App Engine
This is Rietveld 408576698