OLD | NEW |
| (Empty) |
1 <!-- | |
2 Copyright 2013 Google Inc. All Rights Reserved. | |
3 | |
4 Licensed under the Apache License, Version 2.0 (the "License"); | |
5 you may not use this file except in compliance with the License. | |
6 You may obtain a copy of the License at | |
7 | |
8 http://www.apache.org/licenses/LICENSE-2.0 | |
9 | |
10 Unless required by applicable law or agreed to in writing, software | |
11 distributed under the License is distributed on an "AS IS" BASIS, | |
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 See the License for the specific language governing permissions and | |
14 limitations under the License. | |
15 --> | |
16 | |
17 <!-- | |
18 Requires the test harness to allow tests to be added after page load. See | |
19 https://github.com/web-animations/web-animations-js/issues/321 | |
20 --> | |
21 | |
22 <!DOCTYPE html><meta charset="UTF-8"> | |
23 <style type="text/css"> | |
24 video { | |
25 width: 100px; | |
26 } | |
27 </style> | |
28 | |
29 <!-- | |
30 Videos are taken from | |
31 http://techslides.com/sample-webm-ogg-and-mp4-video-files-for-html5 | |
32 | |
33 We serve them from a remote host to make sure they are served with a 206 | |
34 response code, to work around Chrome bug | |
35 https://code.google.com/p/chromium/issues/detail?id=121765. | |
36 --> | |
37 <div id="videos"> | |
38 <video preload="auto"> | |
39 <source src="http://web-animations.github.io/web-animations-js/test/testcase
s/small.webm" type="video/webm"> | |
40 <source src="http://web-animations.github.io/web-animations-js/test/testcase
s/small.mp4" type="video/mp4"> | |
41 </video> | |
42 <video preload="auto"> | |
43 <source src="http://web-animations.github.io/web-animations-js/test/testcase
s/small.webm" type="video/webm"> | |
44 <source src="http://web-animations.github.io/web-animations-js/test/testcase
s/small.mp4" type="video/mp4"> | |
45 </video> | |
46 <video preload="auto"> | |
47 <source src="http://web-animations.github.io/web-animations-js/test/testcase
s/small.webm" type="video/webm"> | |
48 <source src="http://web-animations.github.io/web-animations-js/test/testcase
s/small.mp4" type="video/mp4"> | |
49 </video> | |
50 <video preload="auto"> | |
51 <source src="http://web-animations.github.io/web-animations-js/test/testcase
s/small.webm" type="video/webm"> | |
52 <source src="http://web-animations.github.io/web-animations-js/test/testcase
s/small.mp4" type="video/mp4"> | |
53 </video> | |
54 <video preload="auto"> | |
55 <source src="http://web-animations.github.io/web-animations-js/test/testcase
s/small.webm" type="video/webm"> | |
56 <source src="http://web-animations.github.io/web-animations-js/test/testcase
s/small.mp4" type="video/mp4"> | |
57 </video> | |
58 <video preload="auto"> | |
59 <source src="http://web-animations.github.io/web-animations-js/test/testcase
s/small.webm" type="video/webm"> | |
60 <source src="http://web-animations.github.io/web-animations-js/test/testcase
s/small.mp4" type="video/mp4"> | |
61 </video> | |
62 <video preload="auto"> | |
63 <source src="http://web-animations.github.io/web-animations-js/test/testcase
s/small.webm" type="video/webm"> | |
64 <source src="http://web-animations.github.io/web-animations-js/test/testcase
s/small.mp4" type="video/mp4"> | |
65 </video> | |
66 <video preload="auto"> | |
67 <source src="http://web-animations.github.io/web-animations-js/test/testcase
s/small.webm" type="video/webm"> | |
68 <source src="http://web-animations.github.io/web-animations-js/test/testcase
s/small.mp4" type="video/mp4"> | |
69 </video> | |
70 <video preload="auto"> | |
71 <source src="http://web-animations.github.io/web-animations-js/test/testcase
s/small.webm" type="video/webm"> | |
72 <source src="http://web-animations.github.io/web-animations-js/test/testcase
s/small.mp4" type="video/mp4"> | |
73 </video> | |
74 <video preload="auto"> | |
75 <source src="http://web-animations.github.io/web-animations-js/test/testcase
s/small.webm" type="video/webm"> | |
76 <source src="http://web-animations.github.io/web-animations-js/test/testcase
s/small.mp4" type="video/mp4"> | |
77 </video> | |
78 <video preload="auto"> | |
79 <source src="http://web-animations.github.io/web-animations-js/test/testcase
s/small.webm" type="video/webm"> | |
80 <source src="http://web-animations.github.io/web-animations-js/test/testcase
s/small.mp4" type="video/mp4"> | |
81 </video> | |
82 <video preload="auto"> | |
83 <source src="http://web-animations.github.io/web-animations-js/test/testcase
s/small.webm" type="video/webm"> | |
84 <source src="http://web-animations.github.io/web-animations-js/test/testcase
s/small.mp4" type="video/mp4"> | |
85 </video> | |
86 <video preload="auto"> | |
87 <source src="http://web-animations.github.io/web-animations-js/test/testcase
s/small.webm" type="video/webm"> | |
88 <source src="http://web-animations.github.io/web-animations-js/test/testcase
s/small.mp4" type="video/mp4"> | |
89 </video> | |
90 <video preload="auto"> | |
91 <source src="http://web-animations.github.io/web-animations-js/test/testcase
s/small.webm" type="video/webm"> | |
92 <source src="http://web-animations.github.io/web-animations-js/test/testcase
s/small.mp4" type="video/mp4"> | |
93 </video> | |
94 <video preload="auto"> | |
95 <source src="http://web-animations.github.io/web-animations-js/test/testcase
s/small.webm" type="video/webm"> | |
96 <source src="http://web-animations.github.io/web-animations-js/test/testcase
s/small.mp4" type="video/mp4"> | |
97 </video> | |
98 <video preload="auto"> | |
99 <source src="http://web-animations.github.io/web-animations-js/test/testcase
s/small.webm" type="video/webm"> | |
100 <source src="http://web-animations.github.io/web-animations-js/test/testcase
s/small.mp4" type="video/mp4"> | |
101 </video> | |
102 <video preload="auto"> | |
103 <source src="http://web-animations.github.io/web-animations-js/test/testcase
s/small.webm" type="video/webm"> | |
104 <source src="http://web-animations.github.io/web-animations-js/test/testcase
s/small.mp4" type="video/mp4"> | |
105 </video> | |
106 <video preload="auto"> | |
107 <source src="http://web-animations.github.io/web-animations-js/test/testcase
s/small.webm" type="video/webm"> | |
108 <source src="http://web-animations.github.io/web-animations-js/test/testcase
s/small.mp4" type="video/mp4"> | |
109 </video> | |
110 <video preload="auto"> | |
111 <source src="http://web-animations.github.io/web-animations-js/test/testcase
s/small.webm" type="video/webm"> | |
112 <source src="http://web-animations.github.io/web-animations-js/test/testcase
s/small.mp4" type="video/mp4"> | |
113 </video> | |
114 <video preload="auto"> | |
115 <source src="http://web-animations.github.io/web-animations-js/test/testcase
s/small.webm" type="video/webm"> | |
116 <source src="http://web-animations.github.io/web-animations-js/test/testcase
s/small.mp4" type="video/mp4"> | |
117 </video> | |
118 </div> | |
119 | |
120 <script src="../bootstrap.js" nochecks></script> | |
121 <script> | |
122 "use strict"; | |
123 | |
124 var dt = document.timeline; | |
125 | |
126 // Most of these tests require the video to have loaded before they run. | |
127 // However, the test harness does not allow timing_test()s to be started after | |
128 // the page has finished loading. This means that we can't add the video | |
129 // dynamically then wait for it to load before testing. | |
130 // | |
131 // As a best-effort work-around, we include all videos in static HTML with | |
132 // preload="auto" to hint to the browser that they should be loaded | |
133 // immediately. However, this does not guarantee that they will be loaded when | |
134 // the page's load event fires, so the tests are flaky. | |
135 // | |
136 // TODO: Fix the test runner to allow the use of async_test() with | |
137 // timing_test(), which will allow the video elements to be created dynamically. | |
138 // See https://github.com/web-animations/web-animations-js/issues/321 | |
139 var videos = document.getElementById("videos").getElementsByTagName('video'); | |
140 // Cache this length, as videos is a live NodeList. | |
141 var numStaticVideos = videos.length; | |
142 var nextIndex = 0; | |
143 function getNextVideo() { | |
144 if (nextIndex >= numStaticVideos) { | |
145 throw new Error('No more videos!'); | |
146 } | |
147 return videos[nextIndex++]; | |
148 } | |
149 | |
150 function createVideo() { | |
151 // Videos taken from | |
152 // http://techslides.com/sample-webm-ogg-and-mp4-video-files-for-html5 | |
153 var video = document.createElement("video"); | |
154 var webmSource = document.createElement("source"); | |
155 webmSource.setAttribute("src", "small.webm"); | |
156 webmSource.setAttribute("type", "video/webm"); | |
157 video.appendChild(webmSource); | |
158 var mp4Source = document.createElement("source"); | |
159 mp4Source.setAttribute("src", "small.mp4"); | |
160 mp4Source.setAttribute("type", "video/mp4"); | |
161 video.appendChild(mp4Source); | |
162 document.getElementById("videos").appendChild(video); | |
163 return video; | |
164 } | |
165 | |
166 function testOnceVideosLoaded(callback, message) { | |
167 timing_test(function() { | |
168 at(0.0 * 1000, callback); | |
169 }, message); | |
170 } | |
171 | |
172 function createTestMediaReference(mediaElement, timing, parent) { | |
173 return new MediaReference(mediaElement, timing, parent, 0.0); | |
174 } | |
175 | |
176 var expectedVideoLength = 5.568; | |
177 | |
178 | |
179 // Test that MediaReference disables looping. | |
180 test(function() { | |
181 var video = getNextVideo(); | |
182 video.loop = true; | |
183 createTestMediaReference(video); | |
184 assert_false(video.loop); | |
185 }, "MediaReference should disable looping"); | |
186 | |
187 // Test intrinsic iteration duration before media loads. | |
188 test(function() { | |
189 assert_equals(createTestMediaReference(createVideo()).duration, | |
190 Infinity); | |
191 }, "Intrinsic duration should be Infinity before media loads"); | |
192 | |
193 // Test intrinisc iteration duration. | |
194 testOnceVideosLoaded(function() { | |
195 assert_approx_equals( | |
196 createTestMediaReference(getNextVideo()).duration, | |
197 expectedVideoLength, 0.001); | |
198 }, "Intrinsic iteration duration should be media duration"); | |
199 | |
200 // Test that iteration duration can be overridden. | |
201 testOnceVideosLoaded(function() { | |
202 assert_equals(createTestMediaReference(getNextVideo(), 1.0).duration, | |
203 1.0); | |
204 }, "Iteration duration should be overridable"); | |
205 | |
206 // Test basic use. | |
207 timing_test(function() { | |
208 var video = getNextVideo(); | |
209 at(0.0 * 1000, function() { | |
210 dt.play(createTestMediaReference(video)); | |
211 assert_equals(video.playbackRate, 1.0); | |
212 assert_false(video.paused); | |
213 }); | |
214 }, "Basic use"); | |
215 | |
216 // Test clipping where duration limits. Video should be frozen at end | |
217 // of duration. | |
218 timing_test(function() { | |
219 var video = getNextVideo(); | |
220 at(0.0 * 1000, function() { | |
221 dt.play(createTestMediaReference(video, 3.0)); | |
222 }); | |
223 at(3.0 * 1000, function() { | |
224 assert_equals(video.currentTime, 3.0); | |
225 assert_true(video.paused); | |
226 }); | |
227 at(4.0 * 1000, function() { | |
228 assert_equals(video.currentTime, 3.0); | |
229 assert_true(video.paused); | |
230 }); | |
231 }, "Video should be frozen at duration"); | |
232 | |
233 // Test clipping where video length limits. Video should be frozen at end for | |
234 // remainder of duration. | |
235 timing_test(function() { | |
236 var video = getNextVideo(); | |
237 at(0.0 * 1000, function() { | |
238 dt.play(createTestMediaReference(video, video.duration + 2)); | |
239 }); | |
240 // We can't use video.duration here because the video isn't yet loaded. | |
241 at(expectedVideoLength + 1, function() { | |
242 assert_equals(video.currentTime, video.duration); | |
243 assert_true(video.paused); | |
244 }); | |
245 // We can't use video.duration here because the video isn't yet loaded. | |
246 at(expectedVideoLength + 2, function() { | |
247 assert_equals(video.currentTime, video.duration); | |
248 assert_true(video.paused); | |
249 }); | |
250 }, "Video should be frozen at end"); | |
251 | |
252 // Test fill with duration limiting. Video should be frozen at end of | |
253 // duration. | |
254 timing_test(function() { | |
255 var video = getNextVideo(); | |
256 at(0.0 * 1000, function() { | |
257 dt.play(createTestMediaReference(video, 1.0)); | |
258 }); | |
259 at(2.0 * 1000, function() { | |
260 assert_equals(video.currentTime, 1.0); | |
261 assert_equals(video.paused, true); | |
262 }); | |
263 }, "Should freeze video at duration for fill"); | |
264 | |
265 // Test fill with video length limiting. Video should be at end. | |
266 timing_test(function() { | |
267 var video = getNextVideo(); | |
268 at(0.0 * 1000, function() { | |
269 dt.play(createTestMediaReference(video), video.duration + 1.0); | |
270 }); | |
271 // We can't use video.duration here because the video isn't yet loaded. | |
272 at(expectedVideoLength + 2, function() { | |
273 assert_equals(video.currentTime, video.duration); | |
274 }); | |
275 }, "Should freeze video at end for fill"); | |
276 | |
277 // Test no fill. Video should be frozen at start. | |
278 timing_test(function() { | |
279 var video = getNextVideo(); | |
280 at(0.0 * 1000, function() { | |
281 dt.play(createTestMediaReference(video, {fill: "none"})); | |
282 }); | |
283 // We can't use video.duration here because the video isn't yet loaded. | |
284 at(expectedVideoLength + 1, function() { | |
285 assert_equals(video.currentTime, 0); | |
286 assert_equals(video.paused, true); | |
287 }); | |
288 }, "Should freeze video at start for no fill"); | |
289 | |
290 // Test iterations. | |
291 timing_test(function() { | |
292 var video = getNextVideo(); | |
293 at(0.0 * 1000, function() { | |
294 dt.play(createTestMediaReference(video, | |
295 {iterations: 2.0, duration: 1.0 * 1000})); | |
296 }); | |
297 at(1.5 * 1000, function() { | |
298 assert_equals(video.currentTime, 0.5); | |
299 }); | |
300 }, "Video should respect iterations"); | |
301 | |
302 // Test iterationStart. | |
303 timing_test(function() { | |
304 var video = getNextVideo(); | |
305 at(0.0 * 1000, function() { | |
306 dt.play(createTestMediaReference(video, | |
307 {iterationStart: 0.5, duration: 2.0 * 1000})); | |
308 }); | |
309 at(0.5 * 1000, function() { | |
310 assert_equals(video.currentTime, 1.5); | |
311 }); | |
312 }, "Video should respect iterationStart"); | |
313 | |
314 // Test playback rate. | |
315 timing_test(function() { | |
316 var video = getNextVideo(); | |
317 at(0.0 * 1000, function() { | |
318 dt.play(createTestMediaReference(video, {playbackRate: 2.0})); | |
319 }); | |
320 at(1.0 * 1000, function() { | |
321 assert_equals(video.currentTime, 2.0); | |
322 assert_equals(video.playbackRate, 2.0); | |
323 }); | |
324 }, "Video should respect playbackRate"); | |
325 | |
326 // Test heirachy of playback rates. | |
327 timing_test(function() { | |
328 var video = getNextVideo(); | |
329 at(0.0 * 1000, function() { | |
330 dt.play(new AnimationGroup([createTestMediaReference(video, {playbackRate: 1
.5})], | |
331 {playbackRate: 2.5})); | |
332 }); | |
333 at(1.0 * 1000, function() { | |
334 assert_equals(video.currentTime, 3.75); | |
335 assert_equals(video.playbackRate, 3.75); | |
336 }); | |
337 }, "Video should respect playbackRate heirachy"); | |
338 | |
339 // Test interaction with MediaElement.defaultPlaybackRate. | |
340 timing_test(function() { | |
341 var video = getNextVideo(); | |
342 at(0.0 * 1000, function() { | |
343 video.defaultPlaybackRate = 2.5; | |
344 dt.play(createTestMediaReference(video, {playbackRate: 1.5})); | |
345 }); | |
346 at(1.0 * 1000, function() { | |
347 assert_equals(video.currentTime, 3.75); | |
348 assert_equals(video.playbackRate, 3.75); | |
349 }); | |
350 }, "Video should respect playbackRate after setting defaultPlaybackRate"); | |
351 | |
352 // Test reversing. | |
353 timing_test(function() { | |
354 var video = getNextVideo(); | |
355 at(0.0 * 1000, function() { | |
356 dt.play(createTestMediaReference(video, {direction: "reverse"})); | |
357 }); | |
358 at(1.0 * 1000, function() { | |
359 assert_approx_equals(video.currentTime, video.duration - 1.0, 0.0001); | |
360 assert_equals(video.playbackRate, -1.0); | |
361 }); | |
362 }, "Video should respect reversing"); | |
363 | |
364 // Test negative playback rate. | |
365 timing_test(function() { | |
366 var video = getNextVideo(); | |
367 at(0.0 * 1000, function() { | |
368 dt.play(createTestMediaReference(video, {playbackRate: -0.5})); | |
369 }); | |
370 at(1.0 * 1000, function() { | |
371 assert_approx_equals(video.currentTime, video.duration - 0.5, 0.0001); | |
372 assert_equals(video.playbackRate, -0.5); | |
373 }); | |
374 }, "Video should respect negative playbackRate"); | |
375 | |
376 // Test interaction of reversing and playback rate. | |
377 timing_test(function() { | |
378 var video = getNextVideo(); | |
379 at(0.0 * 1000, function() { | |
380 dt.play(new AnimationGroup( | |
381 [createTestMediaReference(video, {playbackRate: -0.5})], | |
382 {playbackRate: 3.0, direction: "reverse"})); | |
383 }); | |
384 at(1.0 * 1000, function() { | |
385 assert_equals(video.currentTime, 1.5); | |
386 assert_equals(video.playbackRate, 1.5); | |
387 }); | |
388 }, "Video should respect reversing and playbackRate"); | |
389 | |
390 // Test zero duration. | |
391 timing_test(function() { | |
392 var video = getNextVideo(); | |
393 at(0.0 * 1000, function() { | |
394 dt.play(createTestMediaReference(video, 0.0)); | |
395 assert_equals(video.currentTime, 0.0); | |
396 }); | |
397 at(1.0 * 1000, function() { | |
398 assert_equals(video.currentTime, 0.0); | |
399 }); | |
400 }, "Video should start at time zero when duration is zero"); | |
401 | |
402 // Test zero intrinsic duration. | |
403 // TODO: Need to find a zero length video. | |
404 | |
405 // Test that media elements are removed from their MediaController. | |
406 timing_test(function() { | |
407 var video = getNextVideo(); | |
408 at(0.0 * 1000, function() { | |
409 video.controller = new MediaController(); | |
410 dt.play(createTestMediaReference(video)); | |
411 assert_equals(video.controller, null); | |
412 }); | |
413 // Seeking the video will throw if the controller has not been detached. | |
414 at(1.0 * 1000, function() { | |
415 assert_equals(video.currentTime, 1.0); | |
416 }); | |
417 }, "Video should be detached from controller when used in MediaReference"); | |
418 | |
419 // Test limited seek ranges. | |
420 // TODO: Need to find a video with limited seek ranges. | |
421 | |
422 // Test that video is paused when its MediaReference is detached from its | |
423 // AnimationPlayer. | |
424 timing_test(function() { | |
425 var video = getNextVideo(); | |
426 var player; | |
427 at(0.0 * 1000, function() { | |
428 player = dt.play(createTestMediaReference(video)); | |
429 }); | |
430 at(1.0 * 1000, function() { | |
431 assert_false(video.paused); | |
432 player.source = null; | |
433 }); | |
434 at(2.0 * 1000, function() { | |
435 assert_true(video.paused); | |
436 }); | |
437 }, "Video should be paused when MediaReference is detached from its AnimationPla
yer"); | |
438 | |
439 </script> | |
OLD | NEW |