test_preload_actions.html (20458B)
1 <!DOCTYPE HTML> 2 <html> 3 <!-- 4 https://bugzilla.mozilla.org/show_bug.cgi?id=548523 5 --> 6 <head> 7 <title>Test for Bug 548523</title> 8 <script src="/tests/SimpleTest/SimpleTest.js"></script> 9 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> 10 <script type="text/javascript" src="manifest.js"></script> 11 </head> 12 <body> 13 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=548523">Mozilla Bug 548523</a> 14 <p id="display"></p> 15 <div id="content" style="display: none"> 16 17 </div> 18 <!-- <button onClick="SimpleTest.finish();">Finish</button> --> 19 <div>Tests complete: <span id="log" style="font-size: small;"></span></div> 20 <pre id="test"> 21 <script type="application/javascript"> 22 23 /** Test for Bug 548523 */ 24 25 SimpleTest.requestCompleteLog(); 26 var manager = new MediaTestManager; 27 28 manager.onFinished = function() { 29 is(gotLoadEvent, true, "Should not have delayed the load event indefinitely"); 30 }; 31 32 var test = getPlayableVideo(gSeekTests); 33 var baseName = test.name; 34 var gTest = test; 35 var bogusSrc = "bogus.duh"; 36 var bogusType = "video/bogus"; 37 var gotLoadEvent = false; 38 var finished = false; 39 40 addLoadEvent(function() {gotLoadEvent=true;}); 41 42 function log(m) { 43 var l = document.getElementById("log"); 44 l.innerHTML += m; 45 } 46 47 function maybeFinish(v, n) { 48 if (v._finished) { 49 return; 50 } 51 v._finished = true; 52 log(n + ","); 53 removeNodeAndSource(v); 54 manager.finished(v.token); 55 } 56 57 function filename(uri) { 58 return uri.substr(uri.lastIndexOf("/")+1); 59 } 60 61 // Every test must have a setup(v) function, and must call maybeFinish() when test is complete. 62 var tests = [ 63 { 64 // 1. Add preload:none video with src to document. Load should halt at NETWORK_IDLE and HAVE_NOTHING, 65 // after receiving a suspend event. Should not receive loaded events until after we call load(). 66 // Note the suspend event is explictly sent by our "stop the load" code, but other tests can't rely 67 // on it for the preload:metadata case, as there can be multiple suspend events when loading metadata. 68 suspend(e) { 69 var v = e.target; 70 is(v._gotLoadStart, true, "(1) Must get loadstart."); 71 is(v._gotLoadedMetaData, false, "(1) Must not get loadedmetadata."); 72 is(v.readyState, v.HAVE_NOTHING, "(1) ReadyState must be HAVE_NOTHING"); 73 // bug 962949 74 // is(v.networkState, v.NETWORK_IDLE, "(1) NetworkState must be NETWORK_IDLE"); 75 maybeFinish(v, 1); 76 }, 77 78 setup(v) { 79 v._gotLoadStart = false; 80 v._gotLoadedMetaData = false; 81 v.preload = "none"; 82 v.addEventListener("loadedmetadata", function(){v._gotLoadedMetaData = true;}); 83 v.addEventListener("loadstart", function(){v._gotLoadStart = true;}); 84 v.addEventListener("suspend", this.suspend); 85 v.src = test.name; 86 document.body.appendChild(v); // Causes implicit load, which will be halted due to preload:none. 87 }, 88 89 name: "test1", 90 }, 91 { 92 // 2. Add preload:metadata video with src to document. Should halt with NETWORK_IDLE, HAVE_CURRENT_DATA 93 // after suspend event and after loadedmetadata. 94 loadeddata(e) { 95 var v = e.target; 96 is(v._gotLoadStart, true, "(2) Must get loadstart."); 97 is(v._gotLoadedMetaData, true, "(2) Must get loadedmetadata."); 98 ok(v.readyState >= v.HAVE_CURRENT_DATA, "(2) ReadyState must be >= HAVE_CURRENT_DATA"); 99 // bug 962949 100 // is(v.networkState, v.NETWORK_IDLE, "(2) NetworkState must be NETWORK_IDLE"); 101 maybeFinish(v, 2); 102 }, 103 104 setup(v) { 105 v._gotLoadStart = false; 106 v._gotLoadedMetaData = false; 107 v.preload = "metadata"; 108 v.addEventListener("loadstart", function(){v._gotLoadStart = true;}); 109 v.addEventListener("loadedmetadata", function(){v._gotLoadedMetaData = true;}); 110 v.addEventListener("loadeddata", this.loadeddata); 111 v.src = test.name; 112 document.body.appendChild(v); // Causes implicit load, which will be halted after 113 // metadata due to preload:metadata. 114 }, 115 116 name: "test2", 117 }, 118 { 119 // 3. Add preload:auto to document. Should receive canplaythrough eventually. 120 canplaythrough(e) { 121 var v = e.target; 122 is(v._gotLoadStart, true, "(3) Must get loadstart."); 123 is(v._gotLoadedMetaData, true, "(3) Must get loadedmetadata."); 124 maybeFinish(v, 3); 125 }, 126 127 setup(v) { 128 v._gotLoadStart = false; 129 v._gotLoadedMetaData = false; 130 v.preload = "auto"; 131 v.addEventListener("loadstart", function(){v._gotLoadStart = true;}); 132 v.addEventListener("loadedmetadata", function(){v._gotLoadedMetaData = true;}); 133 v.addEventListener("canplaythrough", this.canplaythrough); 134 v.src = test.name; // Causes implicit load. 135 document.body.appendChild(v); 136 }, 137 138 name: "test3", 139 }, 140 { 141 // 4. Add preload:none video to document. Call play(), should load then play through. 142 suspend(e) { 143 var v = e.target; 144 if (v._gotSuspend) { 145 return; // We can receive multiple suspend events, like the one after download completes. 146 } 147 v._gotSuspend = true; 148 is(v._gotLoadStart, true, "(4) Must get loadstart."); 149 is(v._gotLoadedMetaData, false, "(4) Must not get loadedmetadata."); 150 is(v.readyState, v.HAVE_NOTHING, "(4) ReadyState must be HAVE_NOTHING"); 151 // bug 962949 152 // is(v.networkState, v.NETWORK_IDLE, "(4) NetworkState must be NETWORK_IDLE"); 153 v.play(); // Should load and play through. 154 }, 155 156 ended(e) { 157 ok(true, "(4) Got playback ended"); 158 maybeFinish(e.target, 4); 159 }, 160 161 setup(v) { 162 v._gotLoadStart = false; 163 v._gotLoadedMetaData = false; 164 v._gotSuspend = false; 165 v.preload = "none"; 166 v.addEventListener("loadedmetadata", function(){v._gotLoadedMetaData = true;}); 167 v.addEventListener("loadstart", function(){v._gotLoadStart = true;}); 168 v.addEventListener("suspend", this.suspend); 169 v.addEventListener("ended", this.ended); 170 v.src = test.name; 171 document.body.appendChild(v); 172 }, 173 174 name: "test4", 175 }, 176 { 177 // 5. preload:none video without resource, add to document, will implicitly start a 178 // preload:none load. Add a src, it shouldn't load. 179 suspend(e) { 180 var v = e.target; 181 is(v._gotLoadStart, true, "(5) Must get loadstart."); 182 is(v._gotLoadedMetaData, false, "(5) Must not get loadedmetadata."); 183 is(v.readyState, v.HAVE_NOTHING, "(5) ReadyState must be HAVE_NOTHING"); 184 // bug 962949 185 // is(v.networkState, v.NETWORK_IDLE, "(5) NetworkState must be NETWORK_IDLE"); 186 maybeFinish(v, 5); 187 }, 188 189 setup(v) { 190 v._gotLoadStart = false; 191 v._gotLoadedMetaData = false; 192 v.preload = "none"; 193 v.addEventListener("loadedmetadata", function(){v._gotLoadedMetaData = true;}); 194 v.addEventListener("loadstart", function(){v._gotLoadStart = true;}); 195 v.addEventListener("suspend", this.suspend); 196 document.body.appendChild(v); // Causes implicit load, which will be halted due to no resource. 197 v.src = test.name; // Load should start, and halt at preload:none. 198 }, 199 200 name: "test5", 201 }, 202 { 203 // 6. preload:none video without resource, add to document, will implicitly start a 204 // preload:none load. Add a source, it shouldn't load. 205 suspend(e) { 206 var v = e.target; 207 is(v._gotLoadStart, true, "(6) Must get loadstart."); 208 is(v._gotLoadedMetaData, false, "(6) Must not get loadedmetadata."); 209 is(v.readyState, v.HAVE_NOTHING, "(6) ReadyState must be HAVE_NOTHING"); 210 // bug 962949 211 // is(v.networkState, v.NETWORK_IDLE, "(6) NetworkState must be NETWORK_IDLE"); 212 maybeFinish(v, 6); 213 }, 214 215 setup(v) { 216 v._gotLoadStart = false; 217 v._gotLoadedMetaData = false; 218 v.preload = "none"; 219 v.addEventListener("loadedmetadata", function(){v._gotLoadedMetaData = true;}); 220 v.addEventListener("loadstart", function(){v._gotLoadStart = true;}); 221 v.addEventListener("suspend", this.suspend); 222 document.body.appendChild(v); // Causes implicit load, which will be halted due to no resource. 223 var s = document.createElement("source"); 224 s.src = test.name; 225 s.type = test.type; 226 v.appendChild(s); // Load should start, and halt at preload:none. 227 }, 228 229 name: "test6", 230 }, 231 { 232 // 7. create a preload:none document with multiple sources, the first of which is invalid. 233 // Add to document, then play. It should load and play through the second source. 234 suspend(e) { 235 var v = e.target; 236 if (v._gotSuspend) 237 return; // We can receive multiple suspend events, like the one after download completes. 238 v._gotSuspend = true; 239 is(v._gotLoadStart, true, "(7) Must get loadstart."); 240 is(v._gotLoadedMetaData, false, "(7) Must not get loadedmetadata."); 241 is(v.readyState, v.HAVE_NOTHING, "(7) ReadyState must be HAVE_NOTHING"); 242 // bug 962949 243 // is(v.networkState, v.NETWORK_IDLE, "(7) NetworkState must be NETWORK_IDLE"); 244 v.play(); // Should load and play through. 245 }, 246 247 ended(e) { 248 ok(true, "(7) Got playback ended"); 249 var v = e.target; 250 is(v._gotErrorEvent, true, "(7) Should get error event from first source load failure"); 251 maybeFinish(v, 7); 252 }, 253 254 setup(v) { 255 v._gotLoadStart = false; 256 v._gotLoadedMetaData = false; 257 v.preload = "none"; 258 v._gotErrorEvent = false; 259 v.addEventListener("loadedmetadata", function(){v._gotLoadedMetaData = true;}); 260 v.addEventListener("loadstart", function(){v._gotLoadStart = true;}); 261 v.addEventListener("suspend", this.suspend); 262 v.addEventListener("ended", this.ended); 263 var s1 = document.createElement("source"); 264 s1.src = "not-a-real-file.404" 265 s1.type = test.type; 266 s1.addEventListener("error", function(){v._gotErrorEvent = true;}); 267 v.appendChild(s1); 268 var s2 = document.createElement("source"); 269 s2.src = test.name; 270 s2.type = test.type; 271 v.appendChild(s2); 272 document.body.appendChild(v); // Causes implicit load, which will be halt at preload:none on the second resource. 273 }, 274 275 name: "test7", 276 }, 277 { 278 // 8. Change preload value from none to metadata should cause metadata to be loaded. 279 loadeddata(e) { 280 var v = e.target; 281 is(v._gotLoadedMetaData, true, "(8) Must get loadedmetadata."); 282 ok(v.readyState >= v.HAVE_CURRENT_DATA, "(8) ReadyState must be >= HAVE_CURRENT_DATA on suspend."); 283 // bug 962949 284 // is(v.networkState, v.NETWORK_IDLE, "(8) NetworkState must be NETWORK_IDLE when load is halted"); 285 maybeFinish(v, 8); 286 }, 287 288 setup(v) { 289 v._gotLoadedMetaData = false; 290 v.preload = "none"; 291 v.addEventListener("loadstart", function(){v.preload = "metadata";}); 292 v.addEventListener("loadedmetadata", function(){v._gotLoadedMetaData = true;}); 293 v.addEventListener("loadeddata", this.loadeddata); 294 v.src = test.name; // Causes implicit load. 295 document.body.appendChild(v); 296 }, 297 298 name: "test8", 299 }, 300 /*{ 301 // 9. Change preload value from metadata to auto should cause entire media to be loaded. 302 // For some reason we don't always receive the canplaythrough event, particuarly on this test. 303 // We've disabled this test until bug 568402 is fixed. 304 canplaythrough: 305 function(e) { 306 var v = e.target; 307 is(v._gotLoadStart, true, "(9) Must get loadstart."); 308 is(v._gotLoadedMetaData, true, "(9) Must get loadedmetadata."); 309 maybeFinish(v, 9); 310 }, 311 312 setup: 313 function(v) { 314 v._gotLoadStart = false; 315 v._gotLoadedMetaData = false; 316 v.preload = "metadata"; 317 v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}, false); 318 v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}, false); 319 v.addEventListener("loadeddata", function(){v.preload = "auto"}, false); 320 v.addEventListener("canplaythrough", this.canplaythrough, false); 321 v.src = test.name; // Causes implicit load. 322 document.body.appendChild(v); 323 }, 324 },*/ 325 { 326 // 10. Change preload value from none to auto should cause entire media to be loaded. 327 canplaythrough(e) { 328 var v = e.target; 329 is(v._gotLoadedMetaData, true, "(10) Must get loadedmetadata."); 330 maybeFinish(v, 10); 331 }, 332 333 setup(v) { 334 v._gotLoadedMetaData = false; 335 v.preload = "none"; 336 v.addEventListener("loadstart", function(){v.preload = "auto";}); 337 v.addEventListener("loadedmetadata", function(){v._gotLoadedMetaData = true;}); 338 v.addEventListener("canplaythrough", this.canplaythrough); 339 v.src = test.name; // Causes implicit load. 340 document.body.appendChild(v); 341 }, 342 343 name: "test10", 344 }, 345 { 346 // 11. Change preload value from none to metadata should cause metadata to load. 347 loadeddata(e) { 348 var v = e.target; 349 is(v._gotLoadedMetaData, true, "(11) Must get loadedmetadata."); 350 ok(v.readyState >= v.HAVE_CURRENT_DATA, "(11) ReadyState must be >= HAVE_CURRENT_DATA."); 351 // bug 962949 352 // is(v.networkState, v.NETWORK_IDLE, "(11) NetworkState must be NETWORK_IDLE."); 353 maybeFinish(v, 11); 354 }, 355 356 setup(v) { 357 v._gotLoadedMetaData = false; 358 v.preload = "none"; 359 v.addEventListener("loadstart", function(){v.preload = "metadata";}); 360 v.addEventListener("loadedmetadata", function(){v._gotLoadedMetaData = true;}); 361 v.addEventListener("loadeddata", this.loadeddata); 362 v.src = test.name; // Causes implicit load. 363 document.body.appendChild(v); 364 }, 365 366 name: "test11", 367 }, 368 { 369 // 13. Change preload value from auto to none after specifying a src 370 // should load according to preload none, no buffering should have taken place 371 suspend(e) { 372 var v = e.target; 373 is(v._gotLoadStart, true, "(13) Must get loadstart."); 374 is(v._gotLoadedMetaData, false, "(13) Must not get loadedmetadata."); 375 is(v.readyState, v.HAVE_NOTHING, "(13) ReadyState must be HAVE_NOTHING"); 376 // bug 962949 377 // is(v.networkState, v.NETWORK_IDLE, "(13) NetworkState must be NETWORK_IDLE"); 378 maybeFinish(v, 13); 379 }, 380 381 setup(v) { 382 v._gotLoadStart = false; 383 v._gotLoadedMetaData = false; 384 v.preload = "auto"; 385 v.src = test.name; 386 v.preload = "none"; 387 v.addEventListener("loadedmetadata", function(){v._gotLoadedMetaData = true;}); 388 v.addEventListener("loadstart", function(){v._gotLoadStart = true;}); 389 v.addEventListener("suspend", this.suspend); 390 document.body.appendChild(v); // Causes implicit load, should load according to preload none 391 document.createElement("source"); 392 }, 393 394 name: "test13", 395 }, 396 { 397 // 14. Add preload:metadata video with src to document. Play(), should play through. 398 loadeddata(e) { 399 var v = e.target; 400 is(v._gotLoadStart, true, "(14) Must get loadstart."); 401 is(v._gotLoadedMetaData, true, "(14) Must get loadedmetadata."); 402 ok(v.readyState >= v.HAVE_CURRENT_DATA, "(14) ReadyState must be >= HAVE_CURRENT_DATA"); 403 // bug 962949 404 // is(v.networkState, v.NETWORK_IDLE, "(14) NetworkState must be NETWORK_IDLE"); 405 v.play(); 406 }, 407 408 ended(e) { 409 ok(true, "(14) Got playback ended"); 410 var v = e.target; 411 maybeFinish(v, 14); 412 }, 413 414 setup(v) { 415 v._gotLoadStart = false; 416 v._gotLoadedMetaData = false; 417 v.preload = "metadata"; 418 v.addEventListener("loadstart", function(){v._gotLoadStart = true;}); 419 v.addEventListener("loadedmetadata", function(){v._gotLoadedMetaData = true;}); 420 v.addEventListener("ended", this.ended); 421 v.addEventListener("loadeddata", this.loadeddata); 422 v.src = test.name; 423 document.body.appendChild(v); // Causes implicit load, which will be halted after 424 // metadata due to preload:metadata. 425 }, 426 427 name: "test14", 428 }, 429 { 430 // 15. Autoplay should override preload:none. 431 ended(e) { 432 ok(true, "(15) Got playback ended."); 433 var v = e.target; 434 maybeFinish(v, 15); 435 }, 436 437 setup(v) { 438 v._gotLoadStart = false; 439 v._gotLoadedMetaData = false; 440 v.preload = "none"; 441 v.autoplay = true; 442 v.addEventListener("loadstart", function(){v._gotLoadStart = true;}); 443 v.addEventListener("loadedmetadata", function(){v._gotLoadedMetaData = true;}); 444 v.addEventListener("ended", this.ended); 445 v.src = test.name; // Causes implicit load. 446 document.body.appendChild(v); 447 448 // Log events for debugging. 449 var events = ["suspend", "play", "canplay", "canplaythrough", "loadstart", "loadedmetadata", 450 "loadeddata", "playing", "ended", "error", "stalled", "emptied", "abort", 451 "waiting", "pause"]; 452 function logEvent(e) { 453 info(e.target.token + ": got " + e.type); 454 } 455 events.forEach(function(e) { 456 v.addEventListener(e, logEvent); 457 }); 458 }, 459 460 name: "test15", 461 }, 462 { 463 // 16. Autoplay should override preload:metadata. 464 ended(e) { 465 ok(true, "(16) Got playback ended."); 466 var v = e.target; 467 maybeFinish(v, 16); 468 }, 469 470 setup(v) { 471 v.preload = "metadata"; 472 v.autoplay = true; 473 v.addEventListener("ended", this.ended); 474 v.src = test.name; // Causes implicit load. 475 document.body.appendChild(v); 476 }, 477 478 name: "test16", 479 }, 480 { 481 // 17. On a preload:none video, adding autoplay should disable preload none, i.e. don't break autoplay! 482 ended(e) { 483 ok(true, "(17) Got playback ended."); 484 var v = e.target; 485 maybeFinish(v, 17); 486 }, 487 488 setup(v) { 489 v.addEventListener("ended", this.ended); 490 v.preload = "none"; 491 document.body.appendChild(v); // Causes implicit load, which will be halted due to preload:none. 492 v.autoplay = true; 493 v.src = test.name; 494 }, 495 496 name: "test17", 497 }, 498 { 499 // 18. On a preload='none' video, call play() before load algorithms's sync 500 // has run, the play() call should override preload='none'. 501 ended(e) { 502 ok(true, "(18) Got playback ended."); 503 var v = e.target; 504 maybeFinish(v, 18); 505 }, 506 507 setup(v) { 508 v.addEventListener("ended", this.ended); 509 v.preload = "none"; 510 v.src = test.name; // Schedules async section to continue load algorithm. 511 document.body.appendChild(v); 512 v.play(); // Should cause preload:none to be overridden. 513 }, 514 515 name: "test18", 516 }, 517 { 518 // 19. Set preload='auto' on first video source then switching preload='none' and swapping the video source to another. 519 // The second video should not start playing as it's preload state has been changed to 'none' from 'auto' 520 setup(v) { 521 v.preload = "auto"; 522 v.src = test.name; 523 // add a listener for when the video has loaded, so we know preload auto has worked 524 v.onloadedmetadata = function() { 525 is(v.preload, "auto", "(19) preload is initially auto"); 526 // set preload state to none and switch video sources 527 v.preload="none"; 528 v.src = test.name + "?asdf"; 529 530 v.onloadedmetadata = function() { 531 ok(false, "(19) 'loadedmetadata' shouldn't fire when preload is none"); 532 } 533 534 var ontimeout = function() { 535 v.removeEventListener("suspend", onsuspend); 536 ok(false, "(19) 'suspend' should've fired"); 537 maybeFinish(v, 19); 538 } 539 var cancel = setTimeout(ontimeout, 10000); 540 541 var onsuspend = function() { 542 v.removeEventListener("suspend", onsuspend); 543 clearTimeout(cancel); 544 is(v.readyState, 0, "(19) no buffering has taken place"); 545 maybeFinish(v, 19); 546 } 547 v.addEventListener("suspend", onsuspend); 548 } 549 document.body.appendChild(v); 550 }, 551 552 name: "test19", 553 } 554 ]; 555 556 var iterationCount = 0; 557 function startTest(t, token) { 558 if (t == tests[0]) { 559 ++iterationCount; 560 info("iterationCount=" + iterationCount); 561 } 562 if (iterationCount == 2) { 563 // Do this series of tests on logically different resources 564 t.name = baseName + "?" + Math.floor(Math.random()*100000); 565 } 566 var v = document.createElement("video"); 567 v.token = token; 568 t.setup(v); 569 manager.started(token); 570 } 571 572 var twiceTests = tests.concat(tests); 573 SimpleTest.waitForExplicitFinish(); 574 SpecialPowers.pushPrefEnv({"set": [["media.cache_size", 40000]]}, beginTest); 575 function beginTest() { 576 manager.runTests(twiceTests, startTest); 577 } 578 </script> 579 </pre> 580 </body> 581 </html>