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

Side by Side Diff: third_party/WebKit/LayoutTests/media/media-play-promise.html

Issue 1576283003: Have HTMLMediaElement::play() return a Promise. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 10 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 unified diff | Download patch
OLDNEW
(Empty)
1 <html>
2 <head>
3 <script src=media-file.js></script>
4 <script src=video-test.js></script>
5
6 <script>
7 // This is testing the behavior of play() with regards to the returned
philipj_slow 2016/02/02 09:56:33 This is a very big test with a mini runner harness
mlamouri (slow - plz ping) 2016/02/03 19:28:57 Ack.
8 // promise. This test file is creating a small framework in order to be able
9 // to test different cases easily and independently of each other.
10 //
11 // All tests have to be part of the TESTS array. When the page is loaded,
12 // first function in the array is ran. A test is considered done when the
13 // promise returned by mediaElement.play() is resolved or rejected. Each
14 // test then needs to call play() once which wraps this logic. When a test
15 // is finished, the next test in the array is ran until the entire array
16 // was processed.
17 //
18 // Each test should start by prting its name in order to facilitate reading
19 // the output.
20
21 function runNextTestOrFinish()
22 {
23 currentTest++;
24 if (currentTest >= TESTS.length) {
25 endTest();
26 return;
27 }
28
29 consoleWrite("");
30 TESTS[currentTest]();
31 }
32
33 function play()
34 {
35 return mediaElement.play().then(function() {
36 consoleWrite("Promise Resolved");
37 }, function(e) {
38 consoleWrite("Promise Failed with " + e.name);
39 }).then(runNextTestOrFinish);
40 }
41
42 function playWithUserGesture()
philipj_slow 2016/02/02 09:56:33 This could also be a problem for w-p-t. What I did
mlamouri (slow - plz ping) 2016/02/03 19:28:57 Where do media/ tests ready for w-p-t live? Are th
philipj_slow 2016/02/04 10:54:20 Imported w-p-t tests all live in LayoutTests/impor
mlamouri (slow - plz ping) 2016/02/18 17:06:06 I would be interested to help converting media tes
philipj_slow 2016/02/19 08:21:47 I was hoping to avoid reviewing these tests in the
43 {
44 if (!window.eventSender) {
45 failTest("No window.eventSender");
46 return;
47 }
48
49 var target = document.querySelector("p");
50 target.onclick = function() {
51 play();
52 target.onclick = null;
53 };
54
55 var boundingRect = target.getBoundingClientRect();
56 var x = boundingRect.left + (boundingRect.width / 2);
57 var y = boundingRect.top + (boundingRect.height / 2);
58
59 eventSender.mouseMoveTo(x, y);
60 eventSender.mouseDown();
61 eventSender.mouseUp();
62 }
63
64 var currentTest = -1;
65
66 var TESTS = [
67 // Test that play() on an element that is currently loading returns a
68 // promise which resolves successfuly.
69 function playLoading()
70 {
71 consoleWrite("playLoading()");
72 internals.settings.setMediaPlaybackRequiresUserGesture(false);
73
74 run("mediaElement = document.createElement('audio')");
75 var mediaFile = findMediaFile("audio", "content/test");
76 run("mediaElement.src = '" + mediaFile + "'");
77
78 waitForEvent('playing');
79 play();
80 },
81
82 // Test that play() on an element that is already loaded returns a
83 // promise which which resolves successfuly.
84 function playLoaded()
85 {
86 consoleWrite("playLoaded()");
87 internals.settings.setMediaPlaybackRequiresUserGesture(false);
88
89 run("mediaElement = document.createElement('audio')");
90 var mediaFile = findMediaFile("audio", "content/test");
91 run("mediaElement.src = '" + mediaFile + "'");
92
93 waitForEvent('playing');
94
95 waitForEvent('canplaythrough', function() {
96 testExpected(HTMLMediaElement.HAVE_ENOUGH_DATA, mediaElement.rea dyState);
97 testExpected(true, mediaElement.paused)
98
99 play();
100 });
101
102 mediaElement.load();
103 },
104
105 // Test that play() on an element when media playback requires a gesture
106 // returns a rejected promise if there is no user gesture.
107 function playRequiresUserGestureAndHasIt()
108 {
109 consoleWrite("playRequiresUserGestureAndHasIt()");
110 internals.settings.setMediaPlaybackRequiresUserGesture(true);
111
112 run("mediaElement = document.createElement('audio')");
113 var mediaFile = findMediaFile("audio", "content/test");
114 run("mediaElement.src = '" + mediaFile + "'");
115
116 waitForEvent('playing');
117 playWithUserGesture();
118 },
119
120 // Test that play() on an element when media playback requires a gesture
121 // returns a resolved promise if there is a user gesture.
122 function playRequiresUserGestureAndDoesNotHaveIt()
123 {
124 consoleWrite("playRequiresUserGestureAndDoesNotHaveIt()");
125 internals.settings.setMediaPlaybackRequiresUserGesture(true);
126
127 run("mediaElement = document.createElement('audio')");
128 var mediaFile = findMediaFile("audio", "content/test");
129 run("mediaElement.src = '" + mediaFile + "'");
130
131 waitForEvent('playing');
132 play();
133 },
134
135 // Test that play() on an element with an unsupported content will
136 // return a rejected promise.
137 function playNotSupportedContent()
138 {
139 consoleWrite("playNotSupportedContent()");
140 internals.settings.setMediaPlaybackRequiresUserGesture(false);
141
142 run("mediaElement = document.createElement('audio')");
143 var mediaFile = findMediaFile("audio", "content/garbage");
144 run("mediaElement.src = '" + mediaFile + "'");
145
146 waitForEvent('playing');
147 waitForEvent('error', function() {
148 testExpected("mediaElement.error", "[object MediaError]");
149 testExpected("mediaElement.error.code", MediaError.MEDIA_ERR_SRC _NOT_SUPPORTED);
150 });
151 play();
152 },
153
154 // Test that play() returns a resolved promise if called after the
155 // element suffered from a decode error.
156 function playDecodeError()
157 {
158 consoleWrite("playDecodeError()");
159 internals.settings.setMediaPlaybackRequiresUserGesture(false);
160
161 run("mediaElement = document.createElement('audio')");
162 var mediaFile = findMediaFile("audio", "content/test");
163 run("mediaElement.src = '" + mediaFile + "'");
164
165 waitForEvent('playing');
166 waitForEvent('error', function() {
167 testExpected("mediaElement.error", "[object MediaError]");
168 testExpected("mediaElement.error.code", MediaError.MEDIA_ERR_DEC ODE);
169 });
170
171 // The setMediaElementNetworkState() method requires metadata to be
172 // available.
173 waitForEvent('loadedmetadata', function() {
174 internals.setMediaElementNetworkState(mediaElement, 6 /* NetworkSt ateDecodeError */);
philipj_slow 2016/02/02 09:56:33 Not a fan of this. It's weird that WebMediaPlayer:
mlamouri (slow - plz ping) 2016/02/03 19:28:57 This is actually testing that the error doesn't re
philipj_slow 2016/02/19 08:21:48 It's the use of setMediaElementNetworkState to sig
175 play();
176 });
177 },
178
179 // Test that play() returns a resolved promise if called after the
180 // element suffered from a network error.
181 function playNetworkError()
182 {
183 consoleWrite("playNetworkError()");
184 internals.settings.setMediaPlaybackRequiresUserGesture(false);
185
186 run("mediaElement = document.createElement('audio')");
187 var mediaFile = findMediaFile("audio", "content/test");
188 run("mediaElement.src = '" + mediaFile + "'");
189
190 waitForEvent('playing');
191 waitForEvent('error', function() {
192 testExpected("mediaElement.error", "[object MediaError]");
193 testExpected("mediaElement.error.code", MediaError.MEDIA_ERR_NET WORK);
194 });
195
196 // The setMediaElementNetworkState() method requires metadata to be
197 // available.
198 waitForEvent('loadedmetadata', function() {
199 internals.setMediaElementNetworkState(mediaElement, 5 /* NetworkSt ateNetworkError */);
200 play();
201 });
202 },
203
204 // Test that play() returns a rejected promise if the element is
205 // suferring from a not supported error.
206 function playWithErrorAlreadySet()
207 {
208 consoleWrite("playWithErrorAlreadySet()");
209 internals.settings.setMediaPlaybackRequiresUserGesture(false);
210
211 run("mediaElement = document.createElement('audio')");
212 var mediaFile = findMediaFile("audio", "content/garbage");
213 run("mediaElement.src = '" + mediaFile + "'");
214
215 run("mediaElement.load()");
216
217 waitForEvent('playing');
218 waitForEvent('error', function() {
219 testExpected("mediaElement.error", "[object MediaError]");
220 testExpected("mediaElement.error.code", MediaError.MEDIA_ERR_SRC _NOT_SUPPORTED);
221 play();
222 });
223 },
224
225 // Test that play() returns a resolved promise if the element had its
226 // source changed after suffering from an error.
227 function playSrcChangedAfterError()
228 {
229 consoleWrite("playSrcChangedAfterError()");
230 internals.settings.setMediaPlaybackRequiresUserGesture(false);
231
232 run("mediaElement = document.createElement('audio')");
233 var mediaFile = findMediaFile("audio", "content/garbage");
234 run("mediaElement.src = '" + mediaFile + "'");
235
236 run("mediaElement.load()");
237
238 waitForEvent('error', function() {
239 testExpected("mediaElement.error", "[object MediaError]");
240 testExpected("mediaElement.error.code", MediaError.MEDIA_ERR_SRC _NOT_SUPPORTED);
241
242 mediaFile = findMediaFile("audio", "content/test");
243 run("mediaElement.src = '" + mediaFile + "'");
244
245 waitForEvent('playing');
246 waitForEvent('loadedmetadata', function() {
247 play();
248 });
249 });
250 },
251
252 // Test that play() returns a rejected promise if the element had an
253 // error and just changed its source.
254 function playRaceWithSrcChangeError()
255 {
256 consoleWrite("playRaceWithSrcChangeError()");
257 internals.settings.setMediaPlaybackRequiresUserGesture(false);
258
259 run("mediaElement = document.createElement('audio')");
260 var mediaFile = findMediaFile("audio", "content/garbage");
261 run("mediaElement.src = '" + mediaFile + "'");
262
263 run("mediaElement.load()");
264
265 waitForEvent('error', function() {
266 testExpected("mediaElement.error", "[object MediaError]");
267 testExpected("mediaElement.error.code", MediaError.MEDIA_ERR_SRC _NOT_SUPPORTED);
268
269 mediaFile = findMediaFile("audio", "content/test");
270 run("mediaElement.src = '" + mediaFile + "'");
271
272 // TODO(mlamouri): if we print the 'playing' event, it seems
273 // that it actually happens later. It's unclear why.
274 play();
275 });
276 },
277
278 // Test that play() returns a resolved promise when calling play() then
279 // pause() on an element that already has enough data to play. In other
280 // words, pause() doesn't cancel play() because it was resolved
281 // immediately.
282 function playFollowedByPauseWhenLoaded()
283 {
284 consoleWrite("playFollowedByPauseWhenLoaded()");
285 internals.settings.setMediaPlaybackRequiresUserGesture(false);
286
287 run("mediaElement = document.createElement('audio')");
288 var mediaFile = findMediaFile("audio", "content/test");
289 run("mediaElement.src = '" + mediaFile + "'");
290
291 run("mediaElement.load()");
292
293 waitForEvent('canplaythrough', function() {
294 waitForEvent('playing');
295 testExpected("mediaElement.readyState", HTMLMediaElement.HAVE_EN OUGH_DATA);
296 play();
297 testExpected("mediaElement.paused", false);
298 mediaElement.pause();
299 testExpected("mediaElement.paused", true);
300 });
301 },
302
303 // Test that play() returns a rejected promise when calling play() then
304 // pause() on an element that doesn't have enough data to play. In other
305 // words, pause() cancels play() before it can be resolved.
306 function playFollowedByPauseWhenLoading()
307 {
308 consoleWrite("playFollowedByPauseWhenLoaded()");
309 internals.settings.setMediaPlaybackRequiresUserGesture(false);
310
311 run("mediaElement = document.createElement('audio')");
312 var mediaFile = findMediaFile("audio", "content/test");
313 run("mediaElement.src = '" + mediaFile + "'");
314
315 waitForEvent('playing');
316 testExpected("mediaElement.readyState", HTMLMediaElement.HAVE_NOTHIN G);
317 play();
318 testExpected("mediaElement.paused", false);
319 mediaElement.pause();
320 testExpected("mediaElement.paused", true);
321 },
322
323 // Test that load() rejects all the pending play() promises.
324 function loadRejectPendingPromises()
325 {
326 consoleWrite("loadRejectPendingPromises()");
327 internals.settings.setMediaPlaybackRequiresUserGesture(false);
328
329 run("mediaElement = document.createElement('audio')");
330
331 play(); // the promise will be left pending.
332
333 waitForEvent('playing');
334 run("mediaElement.load()");
335 },
336
337 // Test that changing the src rejects the pending play() promises.
338 function newSrcRejectPendingPromises()
339 {
340 consoleWrite("newSrcRejectPendingPromises()");
341 internals.settings.setMediaPlaybackRequiresUserGesture(false);
342
343 run("mediaElement = document.createElement('audio')");
344
345 play(); // the promise will be left pending.
346
347 var mediaFile = findMediaFile("audio", "content/test");
348 run("mediaElement.src = '" + mediaFile + "'");
349 },
350 ];
351
352 function start()
353 {
354 runNextTestOrFinish();
355 }
356
357 </script>
358 </head>
359
360 <body onload="start()">
361
362 <p>Test the play() behaviour with regards to the returned promise for media elem ents.</p>
363
364 </body>
365 </html>
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698