| <!doctype HTML> |
| <html> |
| <head> |
| <title>moving <source> element test</title> |
| <script src=video-test.js></script> |
| <script src=media-file.js></script> |
| <script> |
| |
| var testInfo = |
| { |
| current : -1, |
| tests : |
| [ |
| { fcn : moveToEnd, errorCount : 0, moved : null, done : false, iteration : 1}, |
| { fcn : moveToEnd, errorCount : 0, moved : null, done : false, iteration : 2}, |
| { fcn : moveToEnd, errorCount : 0, moved : null, done : false, iteration : 3}, |
| { fcn : moveEarlier, errorCount : 0, moved : null, iteration : 1 }, |
| { fcn : moveEarlier, errorCount : 0, moved : null, iteration : 2 }, |
| { fcn : moveEarlier, errorCount : 0, moved : null, iteration : 3 }, |
| { fcn : moveEarlier, errorCount : 0, moved : null, iteration : 4 } |
| ] |
| }; |
| |
| function findCurrentSourceElement() |
| { |
| var sources = video.getElementsByTagName('source'); |
| var currentSrc = video.currentSrc; |
| var ndx; |
| for (ndx = 0; ndx < sources.length; ++ndx) { |
| if (sources[ndx].src == currentSrc) |
| break; |
| } |
| if (ndx >= sources.length) { |
| failTest(currentSrc + " not found in <source> list"); |
| return null; |
| } |
| return sources[ndx]; |
| } |
| |
| function moveEarlier(test, event) |
| { |
| if (test.done) |
| return; |
| |
| switch (++test.errorCount) |
| { |
| case 1: |
| // Do nothing on the first error event |
| break; |
| |
| case 2: |
| var current = findCurrentSourceElement(); |
| switch (test.iteration) |
| { |
| case 1: |
| consoleWrite("Moving <b>current<" + "/b> <source> element to beginning of list, it should not be processed again."); |
| test.moved = video.removeChild(current); |
| break; |
| case 2: |
| consoleWrite("Moving <b>next<" + "/b> <source> element to beginning of list, it should never processed."); |
| test.moved = video.removeChild(current.nextSibling); |
| break; |
| case 3: |
| consoleWrite("<span> inserted after <b>current<" + "/b> <source> element before it is removed, processing should proceed normally."); |
| var span = document.createElement("span") |
| span.appendChild(document.createTextNode("Your browser doesn't support HTML5 video!")); |
| video.insertBefore(span, current.nextSibling); |
| test.moved = video.removeChild(current); |
| break; |
| case 4: |
| consoleWrite("<span> inserted after <b>next<" + "/b> <source> element before it is removed, processing should proceed normally."); |
| var span = document.createElement("span") |
| span.appendChild(document.createTextNode("Your browser doesn't support HTML5 video!")); |
| video.insertBefore(span, current.nextSibling.nextSibling); |
| test.moved = video.removeChild(current.nextSibling); |
| break; |
| default: |
| failTest("Malformed test data!"); |
| break; |
| } |
| |
| testExpected(test.moved, null, '!='); |
| video.insertBefore(test.moved, video.firstChild); |
| break; |
| |
| default: |
| // We should never get an error for the element we moved. |
| if (event.target == test.moved) { |
| failTest("Error fired for <source> moved to beginning of list."); |
| test.done = true; |
| return; |
| } else if (!event.target.nextSibling) { |
| logResult(true, "<source> moved was not processed"); |
| setTimeout(configureNextTest, 100); |
| } |
| break; |
| } |
| } |
| |
| function moveToEnd(test, event) |
| { |
| switch (++test.errorCount) |
| { |
| case 1: |
| // Do nothing on the first error event |
| break; |
| |
| case 2: |
| var current = findCurrentSourceElement(); |
| switch (test.iteration) |
| { |
| case 1: |
| consoleWrite("Moving <b>previous<" + "/b> <source> element to end of list, it should be processed again."); |
| test.moved = video.removeChild(current.previousSibling); |
| break; |
| case 2: |
| consoleWrite("Moving <b>current<" + "/b> <source> element, it should be processed again."); |
| test.moved = video.removeChild(current); |
| break; |
| case 3: |
| consoleWrite("Moving <b>next<" + "/b> <source> element, it should be processed again."); |
| test.moved = video.removeChild(current.nextSibling); |
| break; |
| default: |
| failTest("Malformed test data!"); |
| break; |
| } |
| |
| testExpected(test.moved, null, '!='); |
| video.appendChild(test.moved); |
| break; |
| |
| default: |
| if (event.target == test.moved) { |
| logResult(true, "<source> moved was processed a second time."); |
| setTimeout(configureNextTest, 100); |
| } else if (!event.target.nextSibling) { |
| // We should never reach the end of the source list since the tests stops |
| // when the error fires for the moved element. |
| failTest("Error never fired for <source> moved!"); |
| } |
| break; |
| } |
| } |
| |
| function runOneTest(evt) |
| { |
| var test = testInfo.tests[testInfo.current]; |
| test.fcn(test, evt); |
| } |
| |
| function addSource(index) |
| { |
| var source = document.createElement('source'); |
| source.src = findMediaFile("video", index + "-" + Date.now()); |
| source.type = mimeTypeForExtension(source.src.split('.').pop()); |
| video.appendChild(source); |
| } |
| |
| function runNextTest() |
| { |
| consoleWrite(""); |
| if (++testInfo.current >= testInfo.tests.length) { |
| consoleWrite("PASS<br>"); |
| endTest(); |
| return; |
| } |
| |
| testInfo.errorCount = 0; |
| video = mediaElement = document.createElement('video'); |
| document.body.appendChild(video); |
| |
| // Add a bunch of source elements with bogus urls because we want to rearrange elements |
| // after the media engine begins processing sources, and we can't predict the delay |
| // between when the media element fires an 'error' event and our handler is called, |
| // but we need to guarantee that there are <source> elements that haven't been processed |
| // when we run the test. |
| for (var ndx = 1; ndx <= 10; ndx++) |
| addSource(ndx); |
| } |
| |
| function configureNextTest() |
| { |
| var videos = document.querySelectorAll('video'); |
| for (var ndx = 0; ndx < videos.length; ++ndx) |
| videos[ndx].parentNode.removeChild(videos[ndx]); |
| video = mediaElement = null; |
| setTimeout(runNextTest, 100); |
| } |
| |
| function setup() |
| { |
| document.addEventListener("error", runOneTest, true); |
| configureNextTest(); |
| } |
| |
| </script> |
| </head> |
| |
| <body> |
| <div>Test to make sure a <source> moved after the media element begins processing |
| is handled correctly.</div> |
| <script>setup()</script> |
| </body> |
| </html> |