<!DOCTYPE HTML> <html> <!-- https://bugzilla.mozilla.org/show_bug.cgi?id=548523 --> <head> <title>Test for Bug 548523</title> <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> <script type="text/javascript" src="manifest.js"></script> </head> <body> <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=548523">Mozilla Bug 548523</a> <p id="display"></p> <div id="content" style="display: none"> </div> <!-- <button onClick="SimpleTest.finish();">Finish</button> --> <div>Tests complete: <span id="log" style="font-size: small;"></span></div> <pre id="test"> <script type="application/javascript"> /** Test for Bug 548523 **/ SimpleTest.requestCompleteLog(); var manager = new MediaTestManager; manager.onFinished = function() { is(gotLoadEvent, true, "Should not have delayed the load event indefinitely"); }; var test = getPlayableVideo(gSeekTests); var baseName = test.name; var gTest = test; var bogusSrc = "bogus.duh"; var bogusType = "video/bogus"; var gotLoadEvent = false; var finished = false; addLoadEvent(function() {gotLoadEvent=true;}); function log(m) { var l = document.getElementById("log"); l.innerHTML += m; } function maybeFinish(v, n) { if (v._finished) { return; } v._finished = true; log(n + ","); removeNodeAndSource(v); manager.finished(v.token); } function filename(uri) { return uri.substr(uri.lastIndexOf("/")+1); } // Every test must have a setup(v) function, and must call maybeFinish() when test is complete. var tests = [ { // 1. Add preload:none video with src to document. Load should halt at NETWORK_IDLE and HAVE_NOTHING, // after receiving a suspend event. Should not receive loaded events until after we call load(). // Note the suspend event is explictly sent by our "stop the load" code, but other tests can't rely // on it for the preload:metadata case, as there can be multiple suspend events when loading metadata. suspend: function(e) { var v = e.target; is(v._gotLoadStart, true, "(1) Must get loadstart."); is(v._gotLoadedMetaData, false, "(1) Must not get loadedmetadata."); is(v.readyState, v.HAVE_NOTHING, "(1) ReadyState must be HAVE_NOTHING"); // bug 962949 // is(v.networkState, v.NETWORK_IDLE, "(1) NetworkState must be NETWORK_IDLE"); maybeFinish(v, 1); }, setup: function(v) { v._gotLoadStart = false; v._gotLoadedMetaData = false; v.preload = "none"; v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}, false); v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}, false); v.addEventListener("suspend", this.suspend, false); v.src = test.name; document.body.appendChild(v); // Causes implicit load, which will be halted due to preload:none. }, name: "test1", }, { // 2. Add preload:metadata video with src to document. Should halt with NETWORK_IDLE, HAVE_CURRENT_DATA // after suspend event and after loadedmetadata. loadeddata: function(e) { var v = e.target; is(v._gotLoadStart, true, "(2) Must get loadstart."); is(v._gotLoadedMetaData, true, "(2) Must get loadedmetadata."); ok(v.readyState >= v.HAVE_CURRENT_DATA, "(2) ReadyState must be >= HAVE_CURRENT_DATA"); // bug 962949 // is(v.networkState, v.NETWORK_IDLE, "(2) NetworkState must be NETWORK_IDLE"); maybeFinish(v, 2); }, setup: function(v) { v._gotLoadStart = false; v._gotLoadedMetaData = false; v.preload = "metadata"; v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}, false); v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}, false); v.addEventListener("loadeddata", this.loadeddata, false); v.src = test.name; document.body.appendChild(v); // Causes implicit load, which will be halted after // metadata due to preload:metadata. }, name: "test2", }, { // 3. Add preload:auto to document. Should receive canplaythrough eventually. canplaythrough: function(e) { var v = e.target; is(v._gotLoadStart, true, "(3) Must get loadstart."); is(v._gotLoadedMetaData, true, "(3) Must get loadedmetadata."); maybeFinish(v, 3); }, setup: function(v) { v._gotLoadStart = false; v._gotLoadedMetaData = false; v.preload = "auto"; v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}, false); v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}, false); v.addEventListener("canplaythrough", this.canplaythrough, false); v.src = test.name; // Causes implicit load. document.body.appendChild(v); }, name: "test3", }, { // 4. Add preload:none video to document. Call play(), should load then play through. suspend: function(e) { var v = e.target; if (v._gotSuspend) { return; // We can receive multiple suspend events, like the one after download completes. } v._gotSuspend = true; is(v._gotLoadStart, true, "(4) Must get loadstart."); is(v._gotLoadedMetaData, false, "(4) Must not get loadedmetadata."); is(v.readyState, v.HAVE_NOTHING, "(4) ReadyState must be HAVE_NOTHING"); // bug 962949 // is(v.networkState, v.NETWORK_IDLE, "(4) NetworkState must be NETWORK_IDLE"); v.play(); // Should load and play through. }, ended: function(e) { ok(true, "(4) Got playback ended"); maybeFinish(e.target, 4); }, setup: function(v) { v._gotLoadStart = false; v._gotLoadedMetaData = false; v._gotSuspend = false; v.preload = "none"; v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}, false); v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}, false); v.addEventListener("suspend", this.suspend, false); v.addEventListener("ended", this.ended, false); v.src = test.name; document.body.appendChild(v); }, name: "test4", }, { // 5. preload:none video without resource, add to document, will implicitly start a // preload:none load. Add a src, it shouldn't load. suspend: function(e) { var v = e.target; is(v._gotLoadStart, true, "(5) Must get loadstart."); is(v._gotLoadedMetaData, false, "(5) Must not get loadedmetadata."); is(v.readyState, v.HAVE_NOTHING, "(5) ReadyState must be HAVE_NOTHING"); // bug 962949 // is(v.networkState, v.NETWORK_IDLE, "(5) NetworkState must be NETWORK_IDLE"); maybeFinish(v, 5); }, setup: function(v) { v._gotLoadStart = false; v._gotLoadedMetaData = false; v.preload = "none"; v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}, false); v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}, false); v.addEventListener("suspend", this.suspend, false); document.body.appendChild(v); // Causes implicit load, which will be halted due to no resource. v.src = test.name; // Load should start, and halt at preload:none. }, name: "test5", }, { // 6. preload:none video without resource, add to document, will implicitly start a // preload:none load. Add a source, it shouldn't load. suspend: function(e) { var v = e.target; is(v._gotLoadStart, true, "(6) Must get loadstart."); is(v._gotLoadedMetaData, false, "(6) Must not get loadedmetadata."); is(v.readyState, v.HAVE_NOTHING, "(6) ReadyState must be HAVE_NOTHING"); // bug 962949 // is(v.networkState, v.NETWORK_IDLE, "(6) NetworkState must be NETWORK_IDLE"); maybeFinish(v, 6); }, setup: function(v) { v._gotLoadStart = false; v._gotLoadedMetaData = false; v.preload = "none"; v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}, false); v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}, false); v.addEventListener("suspend", this.suspend, false); document.body.appendChild(v); // Causes implicit load, which will be halted due to no resource. var s = document.createElement("source"); s.src = test.name; s.type = test.type; v.appendChild(s); // Load should start, and halt at preload:none. }, name: "test6", }, { // 7. create a preload:none document with multiple sources, the first of which is invalid. // Add to document, then play. It should load and play through the second source. suspend: function(e) { var v = e.target; if (v._gotSuspend) return; // We can receive multiple suspend events, like the one after download completes. v._gotSuspend = true; is(v._gotLoadStart, true, "(7) Must get loadstart."); is(v._gotLoadedMetaData, false, "(7) Must not get loadedmetadata."); is(v.readyState, v.HAVE_NOTHING, "(7) ReadyState must be HAVE_NOTHING"); // bug 962949 // is(v.networkState, v.NETWORK_IDLE, "(7) NetworkState must be NETWORK_IDLE"); v.play(); // Should load and play through. }, ended: function(e) { ok(true, "(7) Got playback ended"); var v = e.target; is(v._gotErrorEvent, true, "(7) Should get error event from first source load failure"); maybeFinish(v, 7); }, setup: function(v) { v._gotLoadStart = false; v._gotLoadedMetaData = false; v.preload = "none"; v._gotErrorEvent = false; v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}, false); v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}, false); v.addEventListener("suspend", this.suspend, false); v.addEventListener("ended", this.ended, false); var s1 = document.createElement("source"); s1.src = "not-a-real-file.404" s1.type = test.type; s1.addEventListener("error", function(e){v._gotErrorEvent = true;}, false); v.appendChild(s1); var s2 = document.createElement("source"); s2.src = test.name; s2.type = test.type; v.appendChild(s2); document.body.appendChild(v); // Causes implicit load, which will be halt at preload:none on the second resource. }, name: "test7", }, { // 8. Change preload value from none to metadata should cause metadata to be loaded. loadeddata: function(e) { var v = e.target; is(v._gotLoadedMetaData, true, "(8) Must get loadedmetadata."); ok(v.readyState >= v.HAVE_CURRENT_DATA, "(8) ReadyState must be >= HAVE_CURRENT_DATA on suspend."); // bug 962949 // is(v.networkState, v.NETWORK_IDLE, "(8) NetworkState must be NETWORK_IDLE when load is halted"); maybeFinish(v, 8); }, setup: function(v) { v._gotLoadedMetaData = false; v.preload = "none"; v.addEventListener("loadstart", function(e){v.preload = "metadata";}, false); v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}, false); v.addEventListener("loadeddata", this.loadeddata, false); v.src = test.name; // Causes implicit load. document.body.appendChild(v); }, name: "test8", }, /*{ // 9. Change preload value from metadata to auto should cause entire media to be loaded. // For some reason we don't always receive the canplaythrough event, particuarly on this test. // We've disabled this test until bug 568402 is fixed. canplaythrough: function(e) { var v = e.target; is(v._gotLoadStart, true, "(9) Must get loadstart."); is(v._gotLoadedMetaData, true, "(9) Must get loadedmetadata."); maybeFinish(v, 9); }, setup: function(v) { v._gotLoadStart = false; v._gotLoadedMetaData = false; v.preload = "metadata"; v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}, false); v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}, false); v.addEventListener("loadeddata", function(){v.preload = "auto"}, false); v.addEventListener("canplaythrough", this.canplaythrough, false); v.src = test.name; // Causes implicit load. document.body.appendChild(v); }, },*/ { // 10. Change preload value from none to auto should cause entire media to be loaded. canplaythrough: function(e) { var v = e.target; is(v._gotLoadedMetaData, true, "(10) Must get loadedmetadata."); maybeFinish(v, 10); }, setup: function(v) { v._gotLoadedMetaData = false; v.preload = "none"; v.addEventListener("loadstart", function(e){v.preload = "auto";}, false); v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}, false); v.addEventListener("canplaythrough", this.canplaythrough, false); v.src = test.name; // Causes implicit load. document.body.appendChild(v); }, name: "test10", }, { // 11. Change preload value from none to metadata should cause metadata to load. loadeddata: function(e) { var v = e.target; is(v._gotLoadedMetaData, true, "(11) Must get loadedmetadata."); ok(v.readyState >= v.HAVE_CURRENT_DATA, "(11) ReadyState must be >= HAVE_CURRENT_DATA."); // bug 962949 // is(v.networkState, v.NETWORK_IDLE, "(11) NetworkState must be NETWORK_IDLE."); maybeFinish(v, 11); }, setup: function(v) { v._gotLoadedMetaData = false; v.preload = "none"; v.addEventListener("loadstart", function(e){v.preload = "metadata";}, false); v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}, false); v.addEventListener("loadeddata", this.loadeddata, false); v.src = test.name; // Causes implicit load. document.body.appendChild(v); }, name: "test11", }, { // 13. Change preload value from auto to none after specifying a src // should load according to preload none, no buffering should have taken place suspend: function(e) { var v = e.target; is(v._gotLoadStart, true, "(13) Must get loadstart."); is(v._gotLoadedMetaData, false, "(13) Must not get loadedmetadata."); is(v.readyState, v.HAVE_NOTHING, "(13) ReadyState must be HAVE_NOTHING"); // bug 962949 // is(v.networkState, v.NETWORK_IDLE, "(13) NetworkState must be NETWORK_IDLE"); maybeFinish(v, 13); }, setup: function(v) { v._gotLoadStart = false; v._gotLoadedMetaData = false; v.preload = "auto"; v.src = test.name; v.preload = "none"; v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}, false); v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}, false); v.addEventListener("suspend", this.suspend, false); document.body.appendChild(v); // Causes implicit load, should load according to preload none var s = document.createElement("source"); }, name: "test13", }, { // 14. Add preload:metadata video with src to document. Play(), should play through. loadeddata: function(e) { var v = e.target; is(v._gotLoadStart, true, "(14) Must get loadstart."); is(v._gotLoadedMetaData, true, "(14) Must get loadedmetadata."); ok(v.readyState >= v.HAVE_CURRENT_DATA, "(14) ReadyState must be >= HAVE_CURRENT_DATA"); // bug 962949 // is(v.networkState, v.NETWORK_IDLE, "(14) NetworkState must be NETWORK_IDLE"); v.play(); }, ended: function(e) { ok(true, "(14) Got playback ended"); var v = e.target; maybeFinish(v, 14); }, setup: function(v) { v._gotLoadStart = false; v._gotLoadedMetaData = false; v.preload = "metadata"; v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}, false); v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}, false); v.addEventListener("ended", this.ended, false); v.addEventListener("loadeddata", this.loadeddata, false); v.src = test.name; document.body.appendChild(v); // Causes implicit load, which will be halted after // metadata due to preload:metadata. }, name: "test14", }, { // 15. Autoplay should override preload:none. ended: function(e) { ok(true, "(15) Got playback ended."); var v = e.target; maybeFinish(v, 15); }, setup: function(v) { v._gotLoadStart = false; v._gotLoadedMetaData = false; v.preload = "none"; v.autoplay = true; v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}, false); v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}, false); v.addEventListener("ended", this.ended, false); v.src = test.name; // Causes implicit load. document.body.appendChild(v); // Log events for debugging. var events = ["suspend", "play", "canplay", "canplaythrough", "loadstart", "loadedmetadata", "loadeddata", "playing", "ended", "error", "stalled", "emptied", "abort", "waiting", "pause"]; function logEvent(e) { var v = e.target; info(e.target.token + ": got " + e.type); } events.forEach(function(e) { v.addEventListener(e, logEvent, false); }); }, name: "test15", }, { // 16. Autoplay should override preload:metadata. ended: function(e) { ok(true, "(16) Got playback ended."); var v = e.target; maybeFinish(v, 16); }, setup: function(v) { v.preload = "metadata"; v.autoplay = true; v.addEventListener("ended", this.ended, false); v.src = test.name; // Causes implicit load. document.body.appendChild(v); }, name: "test16", }, { // 17. On a preload:none video, adding autoplay should disable preload none, i.e. don't break autoplay! ended: function(e) { ok(true, "(17) Got playback ended."); var v = e.target; maybeFinish(v, 17); }, setup: function(v) { v.addEventListener("ended", this.ended, false); v.preload = "none"; document.body.appendChild(v); // Causes implicit load, which will be halted due to preload:none. v.autoplay = true; v.src = test.name; }, name: "test17", }, { // 18. On a preload='none' video, call play() before load algorithms's sync // has run, the play() call should override preload='none'. ended: function(e) { ok(true, "(18) Got playback ended."); var v = e.target; maybeFinish(v, 18); }, setup: function(v) { v.addEventListener("ended", this.ended, false); v.preload = "none"; v.src = test.name; // Schedules async section to continue load algorithm. document.body.appendChild(v); v.play(); // Should cause preload:none to be overridden. }, name: "test18", }, { // 19. Set preload='auto' on first video source then switching preload='none' and swapping the video source to another. // The second video should not start playing as it's preload state has been changed to 'none' from 'auto' setup: function(v) { v.preload = "auto"; v.src = test.name; // add a listener for when the video has loaded, so we know preload auto has worked v.onloadedmetadata = function() { is(v.preload, "auto", "(19) preload is initially auto"); // set preload state to none and switch video sources v.preload="none"; v.src = test.name + "?asdf"; v.onloadedmetadata = function() { ok(false, "(19) 'loadedmetadata' shouldn't fire when preload is none"); } var ontimeout = function() { v.removeEventListener("suspend", onsuspend, false); ok(false, "(19) 'suspend' should've fired"); maybeFinish(v, 19); } var cancel = setTimeout(ontimeout, 10000); var onsuspend = function() { v.removeEventListener("suspend", onsuspend, false); clearTimeout(cancel); is(v.readyState, 0, "(19) no buffering has taken place"); maybeFinish(v, 19); } v.addEventListener("suspend", onsuspend, false); } document.body.appendChild(v); }, name: "test19", } ]; var iterationCount = 0; function startTest(test, token) { if (test == tests[0]) { ++iterationCount; info("iterationCount=" + iterationCount); } if (iterationCount == 2) { // Do this series of tests on logically different resources test.name = baseName + "?" + Math.floor(Math.random()*100000); } var v = document.createElement("video"); v.token = token; test.setup(v); manager.started(token); } var twiceTests = tests.concat(tests); SimpleTest.waitForExplicitFinish(); SpecialPowers.pushPrefEnv({"set": [["media.cache_size", 40000]]}, beginTest); function beginTest() { manager.runTests(twiceTests, startTest); } </script> </pre> </body> </html>