diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /dom/media/webvtt/test | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
56 files changed, 10750 insertions, 0 deletions
diff --git a/dom/media/webvtt/test/crashtests/1304948.html b/dom/media/webvtt/test/crashtests/1304948.html new file mode 100644 index 0000000000..667a13d06a --- /dev/null +++ b/dom/media/webvtt/test/crashtests/1304948.html @@ -0,0 +1,33 @@ +<html class="reftest-wait"> +<head> + <title> Bug 1304948 : Crash if a texttrack remove a cue not belongs to it. </title> +</head> +<meta charset="utf-8"> +<script type="text/javascript"> + +window.onload = function() { + var a = document.createElementNS('http://www.w3.org/1999/xhtml', 'video'); + a.src = ""; + document.body.appendChild(a); + var b = a.addTextTrack('chapters', "AAAAAAAAAAAAAAAA", "de"); + var c = new VTTCue(0.6, 0.3, "AA"); + b.addCue(c); + var d = document.createElementNS('http://www.w3.org/1999/xhtml', 'video'); + var e = d.addTextTrack('chapters', "AAAA", "en-US"); + a.currentTime = 2; + a.play(); + try { + // This will queue a TimeMarchesOn task on mainthread, so use + // timer to wait the TimeMarchesOn crash. + e.removeCue(c); + } catch (e) { + if (e.name == "NotFoundError") { + setTimeout(function() { + document.documentElement.removeAttribute("class");}, 0); + } + } +}; + +</script> +</body> +</html> diff --git a/dom/media/webvtt/test/crashtests/1319486.html b/dom/media/webvtt/test/crashtests/1319486.html new file mode 100644 index 0000000000..74bdb2147c --- /dev/null +++ b/dom/media/webvtt/test/crashtests/1319486.html @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<html> +<head> + <title> Bug 1319486 : Crash if a texttrackcue added to different texttracks. </title> +</head> +<body> +<video id=v1></video> +<video id=v2></video> +</body> +<meta charset="utf-8"> +<script type="text/javascript"> + +addEventListener('DOMContentLoaded', function(){ + let cue,tt1,tt2; + v1.play(); + tt1 = v1.addTextTrack('metadata', "", ""); + v1.play(); + v1.currentTime = 8; + cue = new VTTCue(0, 0.5, ""); + tt1.addCue(cue); + tt2 = v2.addTextTrack('captions', "", ""); + tt2.addCue(cue); + tt2.removeCue(cue); + tt1.addCue(new VTTCue(0.7, 2, "")); +}); +</script> +</html> diff --git a/dom/media/webvtt/test/crashtests/1533909.html b/dom/media/webvtt/test/crashtests/1533909.html new file mode 100644 index 0000000000..ee73ecb7b8 --- /dev/null +++ b/dom/media/webvtt/test/crashtests/1533909.html @@ -0,0 +1,17 @@ +<script> +function eh1() { + d.track.addCue(new VTTCue(0.01, 0.69, "Y")) +} +function eh2() { + a.currentTime = 0.43 + c.addEventListener("DOMNodeRemoved", eh1) + a.append(b) + a.appendChild(c) +} +</script> +<canvas id="c"> +<q id="b"> +</canvas> +<audio id="a" src="data:audio/mpeg;base64,/+M4wAAAAAAAAAAAAEluZm8AAAAPAAAAAwAAAbAAqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV////////////////////////////////////////////AAAAAExhdmM1Ny4zOAAAAAAAAAAAAAAAACQAAAAAAAAAAAGwU/hwzwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+MYxAAMkI7huAhMDGQAndv+H5jfIAPmPzGBGeTAZNN7yjsnqd6Fny79M+o4UifnMu/TlDiIP5Q5l9Z/Kdv6VY0gE3JIAAwE/+MYxAgMYJr6WBhGIivjMy/CEK+zM39VVXjMArKgq6DQdrBV0THlqBp0ShrBp8qGsTPw7lXZFVZZY6GytZZYGChgYIGZaiJI/+MYxBEMUJnAABmMYUigMQLIE1yVpphA1UQMRVVVV000iVu000VVVX///6aaVUxBTUUzLjk5LjVVVVVVVVVVVVVVVVVVVVVV"> +<track id="d"></track> +<iframe onload="eh2()"> diff --git a/dom/media/webvtt/test/crashtests/882549.html b/dom/media/webvtt/test/crashtests/882549.html new file mode 100644 index 0000000000..8a720c3e11 --- /dev/null +++ b/dom/media/webvtt/test/crashtests/882549.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<html> + <head> + <script> + var o0 = new VTTCue(0.000, 1.000, 'Bug882549'); + var o1 = o0.getCueAsHTML(); + </script> + </head> + <body> + </body> +</html> +<script> +</script> diff --git a/dom/media/webvtt/test/crashtests/894104.html b/dom/media/webvtt/test/crashtests/894104.html new file mode 100644 index 0000000000..d021994e74 --- /dev/null +++ b/dom/media/webvtt/test/crashtests/894104.html @@ -0,0 +1,20 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="UTF-8"> +<script> + +function boom() +{ + var frame = document.getElementById("f"); + var frameWin = frame.contentWindow; + frameWin.VTTCue; + document.body.removeChild(frame); + new frameWin.VTTCue(0, 1, "Bug 894104").getCueAsHTML(); +} + +</script> +</head> + +<body onload="boom();"><iframe id="f" src="data:text/html,1"></iframe></body> +</html> diff --git a/dom/media/webvtt/test/crashtests/crashtests.list b/dom/media/webvtt/test/crashtests/crashtests.list new file mode 100644 index 0000000000..c9776984bc --- /dev/null +++ b/dom/media/webvtt/test/crashtests/crashtests.list @@ -0,0 +1,5 @@ +load 1304948.html +load 1319486.html +load 1533909.html +load 882549.html +load 894104.html diff --git a/dom/media/webvtt/test/mochitest/bad-signature.vtt b/dom/media/webvtt/test/mochitest/bad-signature.vtt new file mode 100644 index 0000000000..c9a59b35e9 --- /dev/null +++ b/dom/media/webvtt/test/mochitest/bad-signature.vtt @@ -0,0 +1 @@ +WEB diff --git a/dom/media/webvtt/test/mochitest/basic.vtt b/dom/media/webvtt/test/mochitest/basic.vtt new file mode 100644 index 0000000000..45646ab868 --- /dev/null +++ b/dom/media/webvtt/test/mochitest/basic.vtt @@ -0,0 +1,29 @@ +WEBVTT +REGION +id:testOne lines:2 width:30% +REGION +id:testTwo lines:4 width:20% + +1 +00:00.500 --> 00:00.700 region:testOne +This + +2 +00:01.200 --> 00:02.400 region:testTwo +Is + +2.5 +00:02.000 --> 00:03.500 region:testOne +(Over here?!) + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +5 +00:03.217 --> 00:03.989 +And more! diff --git a/dom/media/webvtt/test/mochitest/bug883173.vtt b/dom/media/webvtt/test/mochitest/bug883173.vtt new file mode 100644 index 0000000000..61f086bcce --- /dev/null +++ b/dom/media/webvtt/test/mochitest/bug883173.vtt @@ -0,0 +1,16 @@ +WEBVTT + +00:03.000 --> 00:04.000 +Should display fifth. + +00:01.000 --> 00:02.000 +Should display first. + +00:01.000 --> 00:03.000 +Should display second. + +00:02.000 --> 00:04.000 +Should display forth. + +00:02.000 --> 00:03.000 +Should display third. diff --git a/dom/media/webvtt/test/mochitest/long.vtt b/dom/media/webvtt/test/mochitest/long.vtt new file mode 100644 index 0000000000..23984b0c8d --- /dev/null +++ b/dom/media/webvtt/test/mochitest/long.vtt @@ -0,0 +1,8001 @@ +WEBVTT + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test + +1 +00:00.500 --> 00:00.700 +This + +2 +00:01.200 --> 00:02.400 +Is + +3 +00:02.710 --> 00:02.910 +A + +4 +00:03.217 --> 00:03.989 +Test diff --git a/dom/media/webvtt/test/mochitest/manifest.js b/dom/media/webvtt/test/mochitest/manifest.js new file mode 100644 index 0000000000..91c481feb9 --- /dev/null +++ b/dom/media/webvtt/test/mochitest/manifest.js @@ -0,0 +1,27 @@ +// Force releasing decoder to avoid timeout in waiting for decoding resource. +function removeNodeAndSource(n) { + n.remove(); + // reset |srcObject| first since it takes precedence over |src|. + n.srcObject = null; + n.removeAttribute("src"); + n.load(); + while (n.firstChild) { + n.firstChild.remove(); + } +} + +function once(target, name, cb) { + var p = new Promise(function (resolve, reject) { + target.addEventListener( + name, + function () { + resolve(); + }, + { once: true } + ); + }); + if (cb) { + p.then(cb); + } + return p; +} diff --git a/dom/media/webvtt/test/mochitest/mochitest.ini b/dom/media/webvtt/test/mochitest/mochitest.ini new file mode 100644 index 0000000000..ee905144b8 --- /dev/null +++ b/dom/media/webvtt/test/mochitest/mochitest.ini @@ -0,0 +1,50 @@ +[DEFAULT] +subsuite = media +tags = webvtt +skip-if = (os == "win" && processor == "aarch64") # aarch64 due to 1536604 +support-files = + ../../../test/gizmo.mp4 + ../../../test/seek.webm + ../../../test/vp9cake.webm + bad-signature.vtt + basic.vtt + bug883173.vtt + long.vtt + manifest.js + parser.vtt + region.vtt + sequential.vtt + vttPositionAlign.vtt + +[test_bug1018933.html] +[test_bug1242594.html] +[test_bug883173.html] +skip-if = (android_version == '25' && debug) # android(bug 1232305) +[test_bug895091.html] +skip-if = (android_version == '25' && debug) # android(bug 1232305) +[test_bug957847.html] +skip-if = (android_version == '25' && debug) # android(bug 1232305) +[test_trackelementevent.html] +[test_trackelementsrc.html] +[test_texttrack.html] +[test_texttrackcue.html] +[test_texttrackcue_moz.html] +[test_trackevent.html] +[test_texttrackevents_video.html] +[test_texttracklist.html] +[test_texttracklist_moz.html] +[test_texttrackregion.html] +[test_testtrack_cors_no_response.html] +[test_texttrack_cors_preload_none.html] +[test_texttrack_mode_change_during_loading.html] +skip-if = true + toolkit == 'android' # Bug 1636572, android(bug 1562021) +[test_texttrack_moz.html] +[test_vttparser.html] +[test_webvtt_empty_displaystate.html] +[test_webvtt_event_same_time.html] +[test_webvtt_infinite_processing_loop.html] +[test_webvtt_overlapping_time.html] +[test_webvtt_positionalign.html] +[test_webvtt_seeking.html] +[test_webvtt_update_display_after_adding_or_removing_cue.html] diff --git a/dom/media/webvtt/test/mochitest/parser.vtt b/dom/media/webvtt/test/mochitest/parser.vtt new file mode 100644 index 0000000000..2a56c65f80 --- /dev/null +++ b/dom/media/webvtt/test/mochitest/parser.vtt @@ -0,0 +1,6 @@ +WEBVTT + +00:00.500 --> 00:00.700 +Test +00:00.500 --> 00:00.700 +Stuff diff --git a/dom/media/webvtt/test/mochitest/region.vtt b/dom/media/webvtt/test/mochitest/region.vtt new file mode 100644 index 0000000000..1e351dbcfb --- /dev/null +++ b/dom/media/webvtt/test/mochitest/region.vtt @@ -0,0 +1,6 @@ +WEBVTT +REGION +id:fred width:62% lines:5 regionanchor:4%,78% viewportanchor:10%,90% scroll:up + +00:01.000 --> 00:02.000 region:fred +Test here. diff --git a/dom/media/webvtt/test/mochitest/sequential.vtt b/dom/media/webvtt/test/mochitest/sequential.vtt new file mode 100644 index 0000000000..94e92e38ae --- /dev/null +++ b/dom/media/webvtt/test/mochitest/sequential.vtt @@ -0,0 +1,10 @@ +WEBVTT + +00:01.000 --> 00:02.000 +This + +00:03.000 --> 00:04.000 +Is + +00:05.000 --> 00:06.000 +A Test diff --git a/dom/media/webvtt/test/mochitest/test_bug1018933.html b/dom/media/webvtt/test/mochitest/test_bug1018933.html new file mode 100644 index 0000000000..bff1db6021 --- /dev/null +++ b/dom/media/webvtt/test/mochitest/test_bug1018933.html @@ -0,0 +1,50 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1018933 +--> +<head> + <meta charset='utf-8'> + <title>Regression test for bug 1018933 - HTMLTrackElement should create only one TextTrack</title> + <script type="text/javascript" src="/MochiKit/MochiKit.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<p id="display"></p> +<div id="content"> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> +SimpleTest.waitForExplicitFinish(); + +var video = document.createElement("video"); +video.src = "seek.webm"; +video.preload = "auto"; + +var trackElement = document.createElement("track"); +trackElement.src = "basic.vtt"; +trackElement.kind = "subtitles"; + +document.getElementById("content").appendChild(video); +video.appendChild(trackElement); + +// Accessing the track now would have caused the bug as the track element +// shouldn't have had time to bind to the tree yet. +trackElement.track.mode = 'showing'; + +video.addEventListener("loadedmetadata", function run_tests() { + // Re-que run_tests() at the end of the event loop until the track + // element has loaded its data. + if (trackElement.readyState == 1) { + setTimeout(run_tests, 0); + return; + } + + is(video.textTracks.length, 1, "Video should have one TextTrack."); + SimpleTest.finish(); +}); +</script> +</pre> +</body> +</html> diff --git a/dom/media/webvtt/test/mochitest/test_bug1242594.html b/dom/media/webvtt/test/mochitest/test_bug1242594.html new file mode 100644 index 0000000000..25c47948bb --- /dev/null +++ b/dom/media/webvtt/test/mochitest/test_bug1242594.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1242594 +--> +<head> + <meta charset='utf-8'> + <title>Bug 1242594 - Unbind a video element with HTMLTrackElement + should not remove the TextTrack</title> + <script type="text/javascript" src="/MochiKit/MochiKit.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<p id="display"></p> +<div id="content"> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> +SimpleTest.waitForExplicitFinish(); + +var video = document.createElement("video"); +video.src = "seek.webm"; +video.preload = "auto"; + +var trackElement = document.createElement("track"); +trackElement.src = "basic.vtt"; +trackElement.kind = "subtitles"; + +document.getElementById("content").appendChild(video); +video.appendChild(trackElement); + +// Bug 1242599, access video.textTracks.length immediately after +// the track element binds into the media element. +is(video.textTracks.length, 1, "Video should have one TextTrack."); +var parent = video.parentNode; +parent.removeChild(video); +is(video.textTracks.length, 1, "After unbind the video element, should have one TextTrack."); +parent.appendChild(video); +is(video.textTracks.length, 1, "After bind the video element, should have one TextTrack."); +SimpleTest.finish(); + +</script> +</pre> +</body> +</html> diff --git a/dom/media/webvtt/test/mochitest/test_bug883173.html b/dom/media/webvtt/test/mochitest/test_bug883173.html new file mode 100644 index 0000000000..6e95f4e3ca --- /dev/null +++ b/dom/media/webvtt/test/mochitest/test_bug883173.html @@ -0,0 +1,39 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for Bug 883173 - TextTrackCue(List) Sorting</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<video id="v" src="seek.webm" preload="metadata"> + <track src="bug883173.vtt" kind="subtitles" id="default" default> +</video> +<script type="text/javascript"> +/** + * This test is used to ensure that the cues in the cue list should be sorted by + * cues' start time and end time, not the present order in the file. + */ +function runTest() { + let trackElement = document.getElementById("default"); + is(trackElement.readyState, 2, "Track::ReadyState should be set to LOADED."); + + let expected = [[1, 3], [1, 2], [2, 4], [2, 3], [3, 4]]; + let cueList = trackElement.track.cues; + is(cueList.length, expected.length, "Cue list length should be 5."); + + for (let i = 0; i < expected.length; i++) { + is(cueList[i].startTime, expected[i][0], + `Cue's start time should be ${expected[i][0]}`); + is(cueList[i].endTime, expected[i][1], + `Cue's end time should be ${expected[i][1]}`); + } + + SimpleTest.finish(); +} + +SimpleTest.waitForExplicitFinish(); +onload = runTest; +</script> +</body> +</html> diff --git a/dom/media/webvtt/test/mochitest/test_bug895091.html b/dom/media/webvtt/test/mochitest/test_bug895091.html new file mode 100644 index 0000000000..6fa2629283 --- /dev/null +++ b/dom/media/webvtt/test/mochitest/test_bug895091.html @@ -0,0 +1,60 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for Bug 895091 - Integrating vtt.js</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="manifest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<video id="v" src="seek.webm" preload="metadata"> + <track src="long.vtt" kind="subtitles" id="track1"> + <track src="long.vtt" kind="subtitles" id="track2"> +</video> +<script type="text/javascript"> +/** + * This test is used to ensure that we can load two track elements with large + * amount of cues at same time. In this test, both tracks are disable by default, + * we have to enable them in order to start loading. + */ +var trackElement = document.getElementById("track1"); +var trackElementTwo = document.getElementById("track2"); + +async function runTest() { + enableBothTracks(); + await waitUntilBothTracksLoaded(); + checkTrackReadyStateShouldBeLoaded(); + checkCuesAmount(); + SimpleTest.finish(); +} + +SimpleTest.waitForExplicitFinish(); +onload = runTest; + +/** + * The following are test helper functions. + */ +function enableBothTracks() { + // All tracks are `disable` on default. As we won't start loading for disabled + // tracks, we have to change their mode in order to start loading. + trackElement.track.mode = "hidden"; + trackElementTwo.track.mode = "hidden"; +} + +async function waitUntilBothTracksLoaded() { + info(`wait until both tracks finish loading`); + await Promise.all([once(trackElement, "load"), once(trackElementTwo, "load")]); +} + +function checkTrackReadyStateShouldBeLoaded() { + is(trackElement.readyState, 2, "Track::ReadyState should be set to LOADED."); + is(trackElementTwo.readyState, 2, "Track::ReadyState should be set to LOADED."); +} + +function checkCuesAmount() { + is(trackElement.track.cues.length, 2000, "Cue list length should be 2000."); + is(trackElementTwo.track.cues.length, 2000, "Cue list length should be 2000."); +} +</script> +</body> +</html> diff --git a/dom/media/webvtt/test/mochitest/test_bug957847.html b/dom/media/webvtt/test/mochitest/test_bug957847.html new file mode 100644 index 0000000000..8bbea81bf9 --- /dev/null +++ b/dom/media/webvtt/test/mochitest/test_bug957847.html @@ -0,0 +1,30 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=957847 +--> +<head> + <meta charset='utf-8'> + <title>Regression test for bug 957847 - Crash on TextTrack::AddCue </title> + <script type="text/javascript" src="/MochiKit/MochiKit.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> +SimpleTest.waitForExplicitFinish(); + +var trackElement = document.createElement('track'); +trackElement.track.addCue(new VTTCue(0, 1, "A")); + +// We need to assert something for Mochitest to be happy. +ok(true); +SimpleTest.finish(); +</script> +</pre> +</body> +</html> diff --git a/dom/media/webvtt/test/mochitest/test_testtrack_cors_no_response.html b/dom/media/webvtt/test/mochitest/test_testtrack_cors_no_response.html new file mode 100644 index 0000000000..e047f74eb3 --- /dev/null +++ b/dom/media/webvtt/test/mochitest/test_testtrack_cors_no_response.html @@ -0,0 +1,41 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Should not load CORS vtt file when server doesn't respond with correct CORS header</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="manifest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<video preload="none" crossorigin="anonymous"> + <track src="http://example.com/tests/dom/canvas/test/crossorigin/video.sjs?name=tests/dom/media/webvtt/test/mochitest/basic.vtt&type=text/vtt" kind="subtitles" id="default" default> +</video> +<script type="text/javascript"> +/** + * This test is used to ensure that we shouldn't load CORS resource if server + * doesn't respond with correct CORS header. In this situation, loading should + * be expected to fail. + */ +async function runTest() { + await waitUntiTrackLoadError(); + SimpleTest.finish(); +} + +SimpleTest.waitForExplicitFinish(); +runTest(); + +/** + * The following are test helper functions. + */ +async function waitUntiTrackLoadError() { + const trackElement = document.getElementById("default"); + if (trackElement.readyState != 3) { + info(`wait until receiving error event`); + await once(trackElement, "error"); + } + is(trackElement.readyState, 3, "Track::ReadyState should be set to ERROR."); + is(trackElement.track.cues.length, 0, "Cue list length should be 0."); +} +</script> +</body> +</html> diff --git a/dom/media/webvtt/test/mochitest/test_texttrack.html b/dom/media/webvtt/test/mochitest/test_texttrack.html new file mode 100644 index 0000000000..69c4f24bec --- /dev/null +++ b/dom/media/webvtt/test/mochitest/test_texttrack.html @@ -0,0 +1,158 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for Bug 833386 - TextTrackList</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="manifest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<video id="v"> +<script type="text/javascript"> +/** + * This test is used to check different things. + * (1) the default value of track element's attributes + * (2) readonly attributes can't be modifted + * (3) the order of tracks in the media element's track list + */ +var enabledTrackElement = null; + +async function runTest() { + addFourTextTrackElementsToVideo(); + startLoadingVideo(); + await waitUntilEnableTrackLoaded(); + checkTracksStatus(); + SimpleTest.finish(); +} + +SimpleTest.waitForExplicitFinish(); +onload = runTest; + +/** + * The following are test helper functions. + */ +function addFourTextTrackElementsToVideo() { + let video = document.getElementById("v"); + isnot(video.textTracks, undefined, + "HTMLMediaElement::TextTrack() property should be available.") + + let trackList = video.textTracks; + is(trackList.length, 0, "Length should be 0."); + + ok(typeof video.addTextTrack == "function", + "HTMLMediaElement::AddTextTrack() function should be available.") + + // Insert some tracks in an order that is not sorted, we will test if they + // are sorted later. + info(`- Add a track element with label 'third' -`); + video.addTextTrack("subtitles", "third", "en-CA"); + is(trackList.length, 1, "Length should be 1."); + + let textTrack = video.textTracks[0]; + checkAttributesDefaultValue(textTrack); + checkTextTrackMode(textTrack); + checkReadOnlyAttributes(textTrack); + + info(`- Add a track element with label 'first' -`); + let trackOne = document.createElement("track"); + video.appendChild(trackOne); + trackOne.label = "first"; + trackOne.src = "basic.vtt"; + trackOne.default = true; + trackOne.id = "2"; + // The automatic track selection would choose the first track element with + // `default` attribute, so this track would be enable later. + enabledTrackElement = trackOne; + + info(`- Add a track element with label 'fourth' -`); + video.addTextTrack("subtitles", "fourth", "en-CA"); + + info(`- Add a track element with label 'second' -`); + let trackTwo = document.createElement("track"); + video.appendChild(trackTwo); + trackTwo.label = "second"; + trackTwo.src = "basic.vtt"; + // Although this track has `default` attribute as well, it won't be enable by + // the automatic track selection because it's not the first default track in + // the media element's track list. + trackTwo.default = true; +} + +function checkAttributesDefaultValue(track) { + is(track.label, "third", "Label should be set to third."); + is(track.language, "en-CA", "Language should be en-CA."); + is(track.kind, "subtitles", "Default kind should be subtitles."); + is(track.mode, "hidden", "Default mode should be hidden."); +} + +function checkTextTrackMode(track) { + // Mode should not allow a bogus value. + track.mode = 'bogus'; + is(track.mode, 'hidden', "Mode should be not allow a bogus value."); + + // Should allow all these values for mode. + changeTextTrackMode("showing"); + changeTextTrackMode("disabled"); + changeTextTrackMode("hidden"); + + function changeTextTrackMode(mode) { + track.mode = mode; + is(track.mode, mode, `Mode should allow \"${mode}\"`); + } +} + +function checkReadOnlyAttributes(track) { + // All below are read-only properties and so should not allow setting. + track.label = "French subtitles"; + is(track.label, "third", "Label is read-only so should still be \"label\"."); + track.language = "en"; + is(track.language, "en-CA", "Language is read-only so should still be \"en-CA\"."); + track.kind = "captions"; + is(track.kind, "subtitles", "Kind is read-only so should still be \"subtitles\""); +} + +function startLoadingVideo() { + let video = document.getElementById("v"); + video.src = "seek.webm"; + video.preload = "metadata"; +} + +async function waitUntilEnableTrackLoaded() { + info(`wait until the enabled track finishes loading`); + await once(enabledTrackElement, "load"); + is(enabledTrackElement.readyState, 2, "Track::ReadyState should be set to LOADED."); +} + +function checkTracksStatus() { + // We're testing two things here, + // (1) the tracks created from a track element have a default mode 'disabled' + // and tracks created from 'addTextTrack' method have a default + // mode of 'hidden'. + // (2) we're testing that the tracks are sorted properly. For the tracks to + // be sorted the first two tracks, added through a TrackElement, must occupy + // the first two indexes in their TrackElement tree order. The second two + // tracks, added through the 'addTextTrack' method, will occupy the last two + // indexes in the order that they were added in. + let trackData = [ + { label: "first", mode: "showing", id: "2" }, + { label: "second", mode: "disabled", id: "" }, + { label: "third", mode: "hidden", id: "" }, + { label: "fourth", mode: "hidden", id: "" } + ]; + let video = document.getElementById("v"); + is(video.textTracks.length, trackData.length, + `TextTracks length should be ${trackData.length}`); + for (let i = 0; i < trackData.length; i++) { + let track = video.textTracks[i]; + isnot(track, null, `Video should have a text track at index ${i}`); + let info = trackData[i]; + for (let key in info) { + is(track[key], info[key], + `Track at index ${i} should have a '${key}' property with a value of '${info[key]}'.`); + } + } +} + +</script> +</body> +</html> diff --git a/dom/media/webvtt/test/mochitest/test_texttrack_cors_preload_none.html b/dom/media/webvtt/test/mochitest/test_texttrack_cors_preload_none.html new file mode 100644 index 0000000000..6743e8c4cd --- /dev/null +++ b/dom/media/webvtt/test/mochitest/test_texttrack_cors_preload_none.html @@ -0,0 +1,40 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>load CORS Text track correctly when its parent media element's preload is none</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="manifest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<video preload="none" crossorigin="anonymous"> + <track src="http://example.com/tests/dom/canvas/test/crossorigin/video.sjs?name=tests/dom/media/webvtt/test/mochitest/basic.vtt&type=text/vtt&cors=anonymous" kind="subtitles" id="default" default> +</video> +<script type="text/javascript"> +/** + * This test is used to test the text track element with CORS resource can starts + * loaded correctly when its parent media element's preload attribute is none. + */ +async function runTest() { + await waitUntiTrackLoaded(); + SimpleTest.finish(); +} + +SimpleTest.waitForExplicitFinish(); +runTest(); + +/** + * The following are test helper functions. + */ +async function waitUntiTrackLoaded() { + let trackElement = document.getElementById("default"); + if (trackElement.readyState != 2) { + info(`wait until the track finishes loading`); + await once(trackElement, "load"); + } + is(trackElement.readyState, 2, "Track::ReadyState should be set to LOADED."); + is(trackElement.track.cues.length, 6, "Cue list length should be 6."); +} +</script> +</body> +</html> diff --git a/dom/media/webvtt/test/mochitest/test_texttrack_mode_change_during_loading.html b/dom/media/webvtt/test/mochitest/test_texttrack_mode_change_during_loading.html new file mode 100644 index 0000000000..974f452092 --- /dev/null +++ b/dom/media/webvtt/test/mochitest/test_texttrack_mode_change_during_loading.html @@ -0,0 +1,75 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>WebVTT : changing track's mode during loading</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="manifest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<script class="testbody" type="text/javascript"> +/** + * This test is to ensure that we won't get `error` event when we change track's + * mode during loading. In this test, track element starts loading after setting + * the src and we would start another load later just after the channel which is + * used to fetch data starts. The second load is triggered by mode changes, and + * it should stop the prevous load and won't generate any error. + */ +async function startTest() { + const video = createVideo(); + const trackElement = createAndAppendtrackElemententToVideo(video); + + await changeTrackModeDuringLoading(trackElement); + await waitUntilTrackLoaded(trackElement); + + removeNodeAndSource(video); + SimpleTest.finish(); +} + +SimpleTest.waitForExplicitFinish(); +SpecialPowers.pushPrefEnv({"set": [["media.webvtt.testing.events", true]]}, + startTest); + +/** + * The following are test helper functions. + */ +function createVideo() { + info(`create video`); + let video = document.createElement("video"); + video.src = "gizmo.mp4"; + document.body.appendChild(video); + return video; +} + +function createAndAppendtrackElemententToVideo(video) { + let trackElement = document.createElement("track"); + trackElement.default = true; + video.append(trackElement); + return trackElement; +} + +async function changeTrackModeDuringLoading(trackElement) { + info(`set src to start loading`); + trackElement.src = "basic.vtt"; + + info(`wait until starting loading resource.`); + await once(trackElement, "mozStartedLoadingTextTrack"); + + info(`changeing track's mode during loading should not cause loading failed.`); + trackElement.onerror = () => { + ok(false, `Should not get error event!`); + } + trackElement.track.mode = "hidden"; +} + +async function waitUntilTrackLoaded(trackElement) { + if (trackElement.readyState != 2) { + info(`wait until the track finishes loading`); + await once(trackElement, "load"); + } + is(trackElement.readyState, 2, "Track::ReadyState should be set to LOADED."); + is(trackElement.track.cues.length, 6, "Cue list length should be 6."); +} +</script> +</body> +</html> diff --git a/dom/media/webvtt/test/mochitest/test_texttrack_moz.html b/dom/media/webvtt/test/mochitest/test_texttrack_moz.html new file mode 100644 index 0000000000..b39562b3a4 --- /dev/null +++ b/dom/media/webvtt/test/mochitest/test_texttrack_moz.html @@ -0,0 +1,60 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for Bug 881976 - TextTrackList</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="manifest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<video id="v" src="seek.webm" preload="metadata"> +<script type="text/javascript"> +/** + * This test is used to ensure the text track list we got from video is as same + * as the one in the text track. + */ +var video = document.getElementById("v"); + +async function runTest() { + addTrackViaAddTrackAPI(); + await addTrackViaTrackElement(); + SimpleTest.finish(); +} + +SimpleTest.waitForExplicitFinish(); +onload = runTest; + +/** + * The following are test helper functions. + */ +function addTrackViaAddTrackAPI() { + // Check if adding a text track manually sets the TextTrackList correctly. + video.addTextTrack("subtitles", "", ""); + // TextTrack.textTrackList is an extension available only to privileged code, + // so we need to access it through the SpecialPowers object. + is(SpecialPowers.unwrap(SpecialPowers.wrap(video.textTracks[0]).textTrackList), + video.textTracks, + "The Track's TextTrackList should be the Video's TextTrackList."); +} + +async function addTrackViaTrackElement() { + // Check if loading a Track via a TrackElement sets the TextTrackList correctly. + let trackElement = document.createElement("track"); + trackElement.src = "basic.vtt"; + trackElement.kind = "subtitles"; + trackElement.default = true; + video.appendChild(trackElement); + + info(`wait until the track finishes loading`); + await once(trackElement, "load"); + + is(trackElement.readyState, HTMLTrackElement.LOADED, + "Track::ReadyState should be set to LOADED."); + is(SpecialPowers.unwrap(SpecialPowers.wrap(trackElement.track).textTrackList), + video.textTracks, + "TrackElement's Track's TextTrackList should be the Video's TextTrackList."); +} + +</script> +</body> +</html> diff --git a/dom/media/webvtt/test/mochitest/test_texttrackcue.html b/dom/media/webvtt/test/mochitest/test_texttrackcue.html new file mode 100644 index 0000000000..3d9783c07d --- /dev/null +++ b/dom/media/webvtt/test/mochitest/test_texttrackcue.html @@ -0,0 +1,298 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for Bug 833386 - HTMLTrackElement</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="manifest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<video id="v" src="seek.webm" preload="metadata"> + <track src="basic.vtt" kind="subtitles" id="default" default> +</video> +<script type="text/javascript"> +/** + * This test is used to test the VTTCue's different behaviors and check whether + * cues would be activatived correctly during video playback. + */ +var video = document.getElementById("v"); +var trackElement = document.getElementById("default"); + +async function runTest() { + await waitUntiTrackLoaded(); + checkCueDefinition(); + checkFirstCueParsedContent(); + checkCueStartTimeAndEndtime(); + checkCueSizeAndPosition(); + checkCueSnapToLines(); + checkCueAlignmentAndWritingDirection(); + checkCueLine(); + checkCreatingNewCue(); + checkRemoveNonExistCue(); + checkActiveCues(); + checkCueRegion(); + await checkCActiveCuesDuringVideoPlaying(); + SimpleTest.finish(); +} + +SimpleTest.waitForExplicitFinish(); +SpecialPowers.pushPrefEnv({"set": [["media.webvtt.regions.enabled", true]]}, + runTest); +/** + * The following are test helper functions. + */ +async function waitUntiTrackLoaded() { + if (trackElement.readyState != 2) { + info(`wait until the track finishes loading`); + await once(trackElement, "load"); + } + is(trackElement.readyState, 2, "Track::ReadyState should be set to LOADED."); + is(trackElement.track.cues.length, 6, "Cue list length should be 6."); +} + +function checkCueDefinition() { + // Check that the typedef of TextTrackCue works in Gecko. + isnot(window.TextTrackCue, undefined, "TextTrackCue should be defined."); + isnot(window.VTTCue, undefined, "VTTCue should be defined."); +} + +function checkFirstCueParsedContent() { + // Check if first cue was parsed correctly. + const cue = trackElement.track.cues[0]; + ok(cue instanceof TextTrackCue, "Cue should be an instanceof TextTrackCue."); + ok(cue instanceof VTTCue, "Cue should be an instanceof VTTCue."); + is(cue.id, "1", "Cue's ID should be 1."); + is(cue.startTime, 0.5, "Cue's start time should be 0.5."); + is(cue.endTime, 0.7, "Cue's end time should be 0.7."); + is(cue.pauseOnExit, false, "Cue's pause on exit flag should be false."); + is(cue.text, "This", "Cue's text should be set correctly."); + is(cue.track, trackElement.track, "Cue's track should be defined."); + cue.track = null; + isnot(cue.track, null, "Cue's track should not be able to be set."); +} + +function checkCueStartTimeAndEndtime() { + const cueList = trackElement.track.cues; + // Check that all cue times were not rounded + is(cueList[1].startTime, 1.2, "Second cue's start time should be 1.2."); + is(cueList[1].endTime, 2.4, "Second cue's end time should be 2.4."); + is(cueList[2].startTime, 2, "Third cue's start time should be 2."); + is(cueList[2].endTime, 3.5, "Third cue's end time should be 3.5."); + is(cueList[3].startTime, 2.71, "Fourth cue's start time should be 2.71."); + is(cueList[3].endTime, 2.91, "Fourth cue's end time should be 2.91."); + is(cueList[4].startTime, 3.217, "Fifth cue's start time should be 3.217."); + is(cueList[4].endTime, 3.989, "Fifth cue's end time should be 3.989."); + is(cueList[5].startTime, 3.217, "Sixth cue's start time should be 3.217."); + is(cueList[5].endTime, 3.989, "Sixth cue's end time should be 3.989."); + + // Check that Cue setters are working correctly. + const cue = trackElement.track.cues[0]; + cue.id = "Cue 01"; + is(cue.id, "Cue 01", "Cue's ID should be 'Cue 01'."); + cue.startTime = 0.51; + is(cue.startTime, 0.51, "Cue's start time should be 0.51."); + cue.endTime = 0.71; + is(cue.endTime, 0.71, "Cue's end time should be 0.71."); + cue.pauseOnExit = true; + is(cue.pauseOnExit, true, "Cue's pause on exit flag should be true."); + video.addEventListener("pause", function() { + video.play(); + }, {once: true}); +} + +function checkCueSizeAndPosition() { + function checkPercentageValue(prop, initialVal) { + ok(prop in cue, prop + " should be a property on VTTCue."); + cue[prop] = initialVal; + is(cue[prop], initialVal, `Cue's ${prop} should initially be ${initialVal}`); + [ 101, -1 ].forEach(function(val) { + let exceptionHappened = false; + try { + cue[prop] = val; + } catch(e) { + exceptionHappened = true; + is(e.name, "IndexSizeError", "Should have thrown IndexSizeError."); + } + ok(exceptionHappened, "Exception should have happened."); + }); + } + + const cue = trackElement.track.cues[0]; + checkPercentageValue("size", 100.0); + cue.size = 50.5; + is(cue.size, 50.5, "Cue's size should be 50.5.") + + // Check cue.position + checkPercentageValue("position", "auto"); + cue.position = 50.5; + is(cue.position, 50.5, "Cue's position value should now be 50.5."); +} + +function checkCueSnapToLines() { + const cue = trackElement.track.cues[0]; + ok(cue.snapToLines, "Cue's snapToLines should be set by set."); + cue.snapToLines = false; + ok(!cue.snapToLines, "Cue's snapToLines should not be set."); +} + +function checkCueAlignmentAndWritingDirection() { + function checkEnumValue(prop, initialVal, acceptedValues) { + ok(prop in cue, `${prop} should be a property on VTTCue.`); + is(cue[prop], initialVal, `Cue's ${prop} should be ${initialVal}`); + cue[prop] = "bogus"; + is(cue[prop], initialVal, `Cue's ${prop} should be ${initialVal}`); + acceptedValues.forEach(function(val) { + cue[prop] = val; + is(cue[prop], val, `Cue's ${prop} should be ${val}`); + if (typeof val === "string") { + cue[prop] = val.toUpperCase(); + is(cue[prop], val, `Cue's ${prop} should be ${val}`); + } + }); + } + + const cue = trackElement.track.cues[0]; + checkEnumValue("align", "center", [ "start", "left", "center", "right", "end" ]); + checkEnumValue("lineAlign", "start", [ "start", "center", "end" ]); + checkEnumValue("vertical", "", [ "", "lr", "rl" ]); + + cue.lineAlign = "center"; + is(cue.lineAlign, "center", "Cue's line align should be center."); + cue.lineAlign = "START"; + is(cue.lineAlign, "center", "Cue's line align should be center."); + cue.lineAlign = "end"; + is(cue.lineAlign, "end", "Cue's line align should be end."); + + // Check that cue position align works properly + is(cue.positionAlign, "auto", "Cue's default position alignment should be auto."); + + cue.positionAlign = "line-left"; + is(cue.positionAlign, "line-left", "Cue's position align should be line-left."); + cue.positionAlign = "auto"; + is(cue.positionAlign, "auto", "Cue's position align should be auto."); + cue.positionAlign = "line-right"; + is(cue.positionAlign, "line-right", "Cue's position align should be line-right."); +} + +function checkCueLine() { + const cue = trackElement.track.cues[0]; + // Check cue.line + is(cue.line, "auto", "Cue's line value should initially be auto."); + cue.line = 0.5; + is(cue.line, 0.5, "Cue's line value should now be 0.5."); + cue.line = "auto"; + is(cue.line, "auto", "Cue's line value should now be auto."); +} + +function checkCreatingNewCue() { + const cueList = trackElement.track.cues; + + // Check that we can create and add new VTTCues + let vttCue = new VTTCue(3.999, 4, "foo"); + is(vttCue.track, null, "Cue's track should be null."); + trackElement.track.addCue(vttCue); + is(vttCue.track, trackElement.track, "Cue's track should be defined."); + is(cueList.length, 7, "Cue list length should now be 7."); + + // Check that new VTTCue was added correctly + let cue = cueList[6]; + is(cue.startTime, 3.999, "Cue's start time should be 3.999."); + is(cue.endTime, 4, "Cue's end time should be 4."); + is(cue.text, "foo", "Cue's text should be foo."); + + // Adding the same cue again should not increase the cue count. + trackElement.track.addCue(vttCue); + is(cueList.length, 7, "Cue list length should be 7."); + + // Check that we are able to remove cues. + trackElement.track.removeCue(cue); + is(cueList.length, 6, "Cue list length should be 6."); +} + +function checkRemoveNonExistCue() { + is(trackElement.track.cues.length, 6, "Cue list length should be 6."); + let exceptionHappened = false; + try { + // We should not be able to remove a cue that is not in the list. + trackElement.track.removeCue(new VTTCue(1, 2, "foo")); + } catch (e) { + // "NotFoundError" should be thrown when trying to remove a cue that is + // not in the list. + is(e.name, "NotFoundError", "Should have thrown NotFoundError."); + exceptionHappened = true; + } + // If this is false then we did not throw an error and probably removed a cue + // when we shouln't have. + ok(exceptionHappened, "Exception should have happened."); + is(trackElement.track.cues.length, 6, "Cue list length should still be 6."); +} + +function checkActiveCues() { + video.currentTime = 2; + isnot(trackElement.track.activeCues, null); + + trackElement.track.mode = "disabled"; + is(trackElement.track.activeCues, null, "No active cue when track is disabled."); + trackElement.track.mode = "showing"; +} + +function checkCueRegion() { + let regionInfo = [ + { lines: 2, width: 30 }, + { lines: 4, width: 20 }, + { lines: 2, width: 30 } + ]; + + for (let i = 0; i < regionInfo.length; i++) { + let cue = trackElement.track.cues[i]; + isnot(cue.region, null, `Cue at ${i} should have a region.`); + for (let key in regionInfo[i]) { + is(cue.region[key], regionInfo[i][key], + `Region should have a ${key} property with a value of ${regionInfo[i][key]}`); + } + } +} + +async function checkCActiveCuesDuringVideoPlaying() { + // Test TextTrack::ActiveCues. + let cueInfo = [ + { startTime: 0.51, endTime: 0.71, ids: ["Cue 01"] }, + { startTime: 0.72, endTime: 1.19, ids: [] }, + { startTime: 1.2, endTime: 1.9, ids: [2] }, + { startTime: 2, endTime: 2.4, ids: [2, 2.5] }, + { startTime: 2.41, endTime: 2.70, ids: [2.5] }, + { startTime: 2.71, endTime: 2.91, ids: [2.5, 3] }, + { startTime: 2.92, endTime: 3.216, ids: [2.5] }, + { startTime: 3.217, endTime: 3.5, ids: [2.5, 4, 5] }, + { startTime: 3.51, endTime: 3.989, ids: [4, 5] }, + { startTime: 3.99, endTime: 4, ids: [] } + ]; + + video.addEventListener("timeupdate", function() { + let activeCues = trackElement.track.activeCues, + playbackTime = video.currentTime; + + for (let i = 0; i < cueInfo.length; i++) { + let cue = cueInfo[i]; + if (playbackTime >= cue.startTime && playbackTime < cue.endTime) { + is(activeCues.length, cue.ids.length, `There should be ${cue.ids.length} currently active cue(s).`); + for (let j = 0; j < cue.ids.length; j++) { + isnot(activeCues.getCueById(cue.ids[j]), undefined, + `The cue with ID ${cue.ids[j]} should be active.`); + } + break; + } + } + }); + + info(`start video from 0s.`); + video.currentTime = 0; + video.play(); + await once(video, "playing"); + info(`video starts playing.`); + await once(video, "ended"); +} + +</script> +</body> +</html> diff --git a/dom/media/webvtt/test/mochitest/test_texttrackcue_moz.html b/dom/media/webvtt/test/mochitest/test_texttrackcue_moz.html new file mode 100644 index 0000000000..29f6661f85 --- /dev/null +++ b/dom/media/webvtt/test/mochitest/test_texttrackcue_moz.html @@ -0,0 +1,34 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=967157 +--> +<head> + <meta charset='utf-8'> + <title>Test for Bug 967157 - Setting TextTrackCue::DisplayState should set TextTrackCue::HasBeenReset to false</title> + <script type="text/javascript" src="/MochiKit/MochiKit.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<p id="display"></p> +<div id="content"> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + SimpleTest.waitForExplicitFinish(); + + var cue = SpecialPowers.wrap(new VTTCue(0, 1, "Some text.")); + is(cue.hasBeenReset, false, "Cue's hasBeenReset flag should be false."); + is(cue.displayState, null, "Cue's displayState should be null."); + + cue.startTime = 0.5; + is(cue.hasBeenReset, true, "Cue's hasBeenReset flag should now be true."); + + cue.displayState = document.createElement("div"); + is(cue.hasBeenReset, false, "Cue's hasBeenReset flag should now be false."); + + SimpleTest.finish(); +</script> +</body> +</html> diff --git a/dom/media/webvtt/test/mochitest/test_texttrackevents_video.html b/dom/media/webvtt/test/mochitest/test_texttrackevents_video.html new file mode 100644 index 0000000000..83104633a4 --- /dev/null +++ b/dom/media/webvtt/test/mochitest/test_texttrackevents_video.html @@ -0,0 +1,91 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Tests for TextTrack DOM Events</title> + <script type="text/javascript" src="/MochiKit/MochiKit.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<p id="display"></p> +<div id="content"> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> +SimpleTest.waitForExplicitFinish(); + +var video = document.createElement("video"); +video.src = "vp9cake.webm"; +video.preload = "auto"; +video.controls = true; +var trackElement = document.createElement("track"); +trackElement.src = "sequential.vtt"; +trackElement.kind = "subtitles"; +trackElement.default = true; +document.getElementById("content").appendChild(video); +video.appendChild(trackElement); + +var trackElementCueChangeCount = 0; +var trackCueChangeCount = 0; +var cueEnterCount = 0; +var cueExitCount = 0; + +video.addEventListener("loadedmetadata", function run_tests() { + // Re-queue run_tests() at the end of the event loop until the track + // element has loaded its data. + if (trackElement.readyState == 1) { + setTimeout(run_tests, 0); + return; + } + is(trackElement.readyState, 2, "Track::ReadyState should be set to LOADED."); + ok('oncuechange' in trackElement.track, "Track::OnCueChange should exist."); + + var textTrack = trackElement.track; + is(textTrack.cues.length, 3, "textTrack.cues.length should 3."); + textTrack.cues[0].onenter = function() { + ++cueEnterCount; + }; + textTrack.cues[0].onexit = function() { + ++cueExitCount; + }; + textTrack.cues[1].onenter = function() { + ++cueEnterCount; + }; + textTrack.cues[1].onexit = function() { + ++cueExitCount; + }; + textTrack.cues[2].onenter = function() { + ++cueEnterCount; + }; + textTrack.cues[2].onexit = function() { + ++cueExitCount; + }; + + trackElement.track.oncuechange = function() { + ++trackElementCueChangeCount; + }; + + trackElement.addEventListener("cuechange", function() { + ++trackCueChangeCount; + }); + + video.play(); +}); + +video.addEventListener('ended', function() { + // Should be fired 1 to 6 times, as there are 3 cues, + // with a change event for when it is activated/deactivated + // (6 events at most). + isnot(trackElementCueChangeCount, 0, "TrackElement should fire cue change at least one time."); + ok(trackElementCueChangeCount <= 6, 'trackElementCueChangeCount should <= 6'); + isnot(trackCueChangeCount, 0, "TrackElement.track should fire cue change at least one time."); + ok(trackCueChangeCount <= 6, 'trackCueChangeCount should <= 6'); + is(cueEnterCount, 3, "cueEnterCount should fire three times."); + is(cueExitCount, 3, "cueExitCount should fire three times."); + SimpleTest.finish() +}); +</script> +</pre> +</body> +</html> diff --git a/dom/media/webvtt/test/mochitest/test_texttracklist.html b/dom/media/webvtt/test/mochitest/test_texttracklist.html new file mode 100644 index 0000000000..c1d2296289 --- /dev/null +++ b/dom/media/webvtt/test/mochitest/test_texttracklist.html @@ -0,0 +1,51 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=882703 +--> +<head> + <meta charset="utf-8"> + <title>Media test: TextTrackList change event</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<p id="display"></p> +<div id="content"> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> +SimpleTest.waitForExplicitFinish(); + +let video = document.createElement("video"); + +isnot(video.textTracks, null, "Video should have a list of TextTracks."); + +video.addTextTrack("subtitles", "", ""); + +let track = video.textTracks[0]; +video.textTracks.addEventListener("change", changed); + +is(track.mode, "hidden", "New TextTrack's mode should be hidden."); +track.mode = "showing"; +// Bug882674: change the mode again to see if we receive only one +// change event. +track.mode = "hidden"; + +var eventCount = 0; +function changed(event) { + eventCount++; + is(eventCount, 1, "change event dispatched multiple times."); + is(event.target, video.textTracks, "change event's target should be video.textTracks."); + ok(event instanceof window.Event, "change event should be a simple event."); + ok(!event.bubbles, "change event should not bubble."); + ok(event.isTrusted, "change event should be trusted."); + ok(!event.cancelable, "change event should not be cancelable."); + + // Delay the finish function call for testing the change event count. + setTimeout(SimpleTest.finish, 0); +} +</script> +</pre> +</body> +</html> diff --git a/dom/media/webvtt/test/mochitest/test_texttracklist_moz.html b/dom/media/webvtt/test/mochitest/test_texttracklist_moz.html new file mode 100644 index 0000000000..6cae8323fd --- /dev/null +++ b/dom/media/webvtt/test/mochitest/test_texttracklist_moz.html @@ -0,0 +1,34 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=881976 +--> +<head> + <meta charset='utf-8'> + <title>Test for Bug 881976 - TextTrackCue Computed Position</title> + <script type="text/javascript" src="/MochiKit/MochiKit.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<p id="display"></p> +<div id="content"> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> +SimpleTest.waitForExplicitFinish(); + +var video = document.createElement("video"); +var trackList = video.textTracks; +ok(trackList instanceof TextTrackList, + "Video's textTracks should be a TextTrackList"); +var trackParent = SpecialPowers.unwrap( + SpecialPowers.wrap(trackList).mediaElement +); +is(trackParent, video, + "Video's TextTrackList's MediaElement reference should be set to the video."); +SimpleTest.finish(); +</script> +</pre> +</body> +</html> diff --git a/dom/media/webvtt/test/mochitest/test_texttrackregion.html b/dom/media/webvtt/test/mochitest/test_texttrackregion.html new file mode 100644 index 0000000000..f41c404445 --- /dev/null +++ b/dom/media/webvtt/test/mochitest/test_texttrackregion.html @@ -0,0 +1,57 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for Bug 917945 - VTTRegion</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="manifest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<video id="v" src="seek.webm" preload="auto"> + <track src="region.vtt" kind="subtitles" id="default" default> +</video> +<script type="text/javascript"> +/** + * This test is used to ensure that we can parse VTT region attributes correctly + * from vtt file. + */ +var trackElement = document.getElementById("default"); + +async function runTest() { + await waitUntiTrackLoaded(); + checkRegionAttributes(); + SimpleTest.finish(); +} + +SimpleTest.waitForExplicitFinish(); +SpecialPowers.pushPrefEnv({"set": [["media.webvtt.regions.enabled", true]]}, + runTest); +/** + * The following are test helper functions. + */ +async function waitUntiTrackLoaded() { + if (trackElement.readyState != 2) { + info(`wait until the track finishes loading`); + await once(trackElement, "load"); + } + is(trackElement.readyState, 2, "Track::ReadyState should be set to LOADED."); +} + +function checkRegionAttributes() { + let cues = trackElement.track.cues; + is(cues.length, 1, "Cue list length should be 1."); + + let region = cues[0].region; + isnot(region, null, "Region should not be null."); + is(region.width, 62, "Region width should be 50."); + is(region.lines, 5, "Region lines should be 5."); + is(region.regionAnchorX, 4, "Region regionAnchorX should be 4."); + is(region.regionAnchorY, 78, "Region regionAnchorY should be 78."); + is(region.viewportAnchorX, 10, "Region viewportAnchorX should be 10."); + is(region.viewportAnchorY, 90, "Region viewportAnchorY should be 90."); + is(region.scroll, "up", "Region scroll should be 'up'"); +} + +</script> +</body> +</html> diff --git a/dom/media/webvtt/test/mochitest/test_trackelementevent.html b/dom/media/webvtt/test/mochitest/test_trackelementevent.html new file mode 100644 index 0000000000..f78033a89d --- /dev/null +++ b/dom/media/webvtt/test/mochitest/test_trackelementevent.html @@ -0,0 +1,77 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for Bug 882677 - Implement the 'sourcing out of band text tracks' algorithm</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="manifest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<video id="v" src="seek.webm" preload="auto"> +<script type="text/javascript"> +/** + * This test is used to ensure that we can load resource from vtt files correctly + * and will dispatch `error` event for invalid vtt files. + */ +var video = document.getElementById("v"); + +async function runTest() { + let tracks = createTextTrackElements(); + appendTracksToVideo(tracks); + await waitUntilsTrackLoadedOrGetError(tracks); + SimpleTest.finish() +} + +SimpleTest.waitForExplicitFinish(); +onload = runTest; + +/** + * The following are test helper functions. + */ +function createTextTrackElements() { + // Only first track has valid vtt resource, other tracks should get the error + // event because of invalid vtt resources. + let trackOne = document.createElement("track"); + trackOne.src = "basic.vtt"; + trackOne.kind = "subtitles"; + trackOne.expectedLoaded = true; + + let trackTwo = document.createElement("track"); + trackTwo.src = "bad-signature.vtt"; + trackTwo.kind = "captions"; + trackTwo.expectedLoaded = false; + + let trackThree = document.createElement("track"); + trackThree.src = "bad.vtt"; + trackThree.kind = "chapters"; + trackThree.expectedLoaded = false; + + return [trackOne, trackTwo, trackThree]; +} + +function appendTracksToVideo(tracks) { + for (let track of tracks) { + video.appendChild(track); + } +} + +async function waitUntilsTrackLoadedOrGetError(tracks) { + let promises = []; + for (let track of tracks) { + // explictly enable those track in order to start loading. + track.track.mode = "hidden"; + if (track.expectedLoaded) { + info(`adding 'load' event to wait list.`); + promises.push(once(track, "load")); + } else { + info(`adding 'error' event to wait list.`); + promises.push(once(track, "error")); + } + } + info(`wait until tracks finish loading or get error.`); + await Promise.all(promises); + ok(true, "all tracks finish loading or get error."); +} +</script> +</body> +</html> diff --git a/dom/media/webvtt/test/mochitest/test_trackelementsrc.html b/dom/media/webvtt/test/mochitest/test_trackelementsrc.html new file mode 100644 index 0000000000..f98e79c605 --- /dev/null +++ b/dom/media/webvtt/test/mochitest/test_trackelementsrc.html @@ -0,0 +1,53 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1281418 - Change the src attribue for TrackElement.</title> + <script type="text/javascript" src="/MochiKit/MochiKit.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> +SimpleTest.waitForExplicitFinish(); + +SpecialPowers.pushPrefEnv({"set": [["media.webvtt.regions.enabled", true]]}, + function() { + var video = document.createElement("video"); + video.src = "seek.webm"; + video.preload = "metadata"; + var trackElement = document.createElement("track"); + trackElement.src = "basic.vtt"; + trackElement.default = true; + + document.getElementById("content").appendChild(video); + video.appendChild(trackElement); + + video.addEventListener("loadedmetadata", function metadata() { + if (trackElement.readyState <= 1) { + setTimeout(metadata, 0); + return; + } + is(video.textTracks.length, 1, "Length should be 1."); + is(video.textTracks[0].cues.length, 6, "Cue length should be 6."); + + trackElement.src = "sequential.vtt"; + trackElement.track.mode = "showing"; + video.play(); + }); + + video.addEventListener("ended", function end() { + is(trackElement.readyState, 2, "readyState should be 2.") + is(video.textTracks.length, 1, "Length should be 1."); + is(video.textTracks[0].cues.length, 3, "Cue length should be 3."); + SimpleTest.finish(); + }); +}); +</script> +</pre> +</body> +</html> diff --git a/dom/media/webvtt/test/mochitest/test_trackevent.html b/dom/media/webvtt/test/mochitest/test_trackevent.html new file mode 100644 index 0000000000..ffba7d33ec --- /dev/null +++ b/dom/media/webvtt/test/mochitest/test_trackevent.html @@ -0,0 +1,69 @@ + +<!DOCTYPE HTML> +<html> +<head> + <title>Test for Bug 893309 - Implement TrackEvent</title> + <script type="text/javascript" src="/MochiKit/MochiKit.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> +SimpleTest.waitForExplicitFinish(); + +var video = document.createElement("video"); +isnot(video.textTracks, undefined, "HTMLMediaElement::TextTrack() property should be available.") +ok(typeof video.addTextTrack == "function", "HTMLMediaElement::AddTextTrack() function should be available.") + +var trackList = video.textTracks; +is(trackList.length, 0, "Length should be 0."); + +var evtTextTrack, numOfCalls = 0, tt; +trackList.onaddtrack = function(event) { + ok(event instanceof TrackEvent, "Fired event from onaddtrack should be a TrackEvent"); + is(event.type, "addtrack", "Event type should be addtrack"); + ok(event.isTrusted, "Event should be trusted!"); + ok(!event.bubbles, "Event shouldn't bubble!"); + ok(!event.cancelable, "Event shouldn't be cancelable!"); + + evtTextTrack = event.track; + tt = textTrack[numOfCalls].track || textTrack[numOfCalls]; + + ok(tt === evtTextTrack, "Text tracks should be the same"); + is(evtTextTrack.label, label[numOfCalls], "Label should be set to "+ label[numOfCalls]); + is(evtTextTrack.language, language[numOfCalls], "Language should be " + language[numOfCalls]); + is(evtTextTrack.kind, kind[numOfCalls], "Kind should be " + kind[numOfCalls]); + + if (++numOfCalls == 4) { + SimpleTest.finish(); + } +}; + +var label = ["Oasis", "Coldplay", "t.A.T.u", ""]; +var language = ["en-CA", "en-GB", "ru", ""]; +var kind = ["subtitles", "captions", "chapters", "subtitles"]; + +var textTrack = new Array(4); +for (var i = 0; i < 3; ++i) { + textTrack[i] = video.addTextTrack(kind[i], label[i], language[i]); + is(trackList.length, i + 1, "Length should be " + (i+1)); +} + +video.src = "seek.webm"; +video.preload = "auto"; +var trackElement = document.createElement("track"); +trackElement.src = "basic.vtt"; +textTrack[3] = trackElement; + +document.getElementById("content").appendChild(video); +video.appendChild(trackElement); + +//TODO: Tests for removetrack event to be added along with bug 882677 +</script> +</pre> +</body> +</html> diff --git a/dom/media/webvtt/test/mochitest/test_vttparser.html b/dom/media/webvtt/test/mochitest/test_vttparser.html new file mode 100644 index 0000000000..419723a1d4 --- /dev/null +++ b/dom/media/webvtt/test/mochitest/test_vttparser.html @@ -0,0 +1,44 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset='utf-8'> + <title>WebVTT Parser Regression Tests</title> + <script type="text/javascript" src="/MochiKit/MochiKit.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<p id="display"></p> +<div id="content"> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> +SimpleTest.waitForExplicitFinish(); + +var video = document.createElement("video"); +video.src = "seek.webm"; +video.preload = "auto"; + +var trackElement = document.createElement("track"); +trackElement.src = "parser.vtt"; +trackElement.kind = "subtitles"; +trackElement.default = true; + +document.getElementById("content").appendChild(video); +video.appendChild(trackElement); +video.addEventListener("loadedmetadata", function run_tests() { + // Re-que run_tests() at the end of the event loop until the track + // element has loaded its data. + if (trackElement.readyState == 1) { + setTimeout(run_tests, 0); + return; + } + + is(trackElement.readyState, 2, "Track::ReadyState should be set to LOADED."); + is(trackElement.track.cues.length, 2, "Track should have two Cues."); + SimpleTest.finish(); +}); +</script> +</pre> +</body> +</html> diff --git a/dom/media/webvtt/test/mochitest/test_webvtt_empty_displaystate.html b/dom/media/webvtt/test/mochitest/test_webvtt_empty_displaystate.html new file mode 100644 index 0000000000..e1a8ddc555 --- /dev/null +++ b/dom/media/webvtt/test/mochitest/test_webvtt_empty_displaystate.html @@ -0,0 +1,98 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset='utf-8'> + <title>WebVTT : cue's displaystate should be empty when its active flag is unset</title> + <script type="text/javascript" src="/MochiKit/MochiKit.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<div id="content"> +</div> +<script class="testbody" type="text/javascript"> +SimpleTest.waitForExplicitFinish(); + +var isReceivedOnEnterEvent = false; +var isReceivedOnExitEvent = false; + +function checkCueEvents() { + ok(isReceivedOnEnterEvent, "Already received cue's onEnter event."); + ok(isReceivedOnExitEvent, "Already received cue's onExit event."); + SimpleTest.finish(); +} + +function checkCueDisplayState(cue, expectedState) { + var cueChrome = SpecialPowers.wrap(cue); + if (expectedState) { + ok(cueChrome.displayState, "Cue's displayState shouldn't be empty."); + } else { + ok(!cueChrome.displayState, "Cue's displayState should be empty."); + } +} + +function runTest() { + info("--- create video ---"); + var video = document.createElement("video"); + video.src = "seek.webm"; + video.autoplay = true; + document.getElementById("content").appendChild(video); + + video.onended = function () { + video.onended = null; + checkCueEvents(); + }; + + video.onpause = function () { + video.onpause = null; + checkCueEvents(); + } + + video.onloadedmetadata = function () { + ok(video.duration > 2, "video.duration should larger than 2"); + } + + info("--- create the type of track ---"); + isnot(window.TextTrack, undefined, "TextTrack should be defined."); + + var track = video.addTextTrack("subtitles", "A", "en"); + track.mode = "showing"; + ok(track instanceof TextTrack, "Track should be an instanceof TextTrack."); + + info("--- check the type of cue ---"); + isnot(window.TextTrackCue, undefined, "TextTrackCue should be defined."); + isnot(window.VTTCue, undefined, "VTTCue should be defined."); + + var cue = new VTTCue(1, 2, "Test cue"); + ok(cue instanceof TextTrackCue, "Cue should be an instanceof TextTrackCue."); + ok(cue instanceof VTTCue, "Cue should be an instanceof VTTCue."); + + info("--- add cue ---"); + track.addCue(cue); + video.ontimeupdate = function () { + info("--- video.currentTime is " + video.currentTime); + }; + cue.onenter = function () { + cue.onenter = null; + isReceivedOnEnterEvent = true; + var cueChrome = SpecialPowers.wrap(cue); + info("cueChrome.getActive " + cueChrome.getActive); + if (cueChrome.getActive) { + checkCueDisplayState(cue, true /* has display-state */); + } else { + info("This is a missing cue, video.currentTime is "+ video.currentTime); + } + + cue.onexit = function () { + cue.onexit = null; + isReceivedOnExitEvent = true; + checkCueDisplayState(cue, false /* no display-state */); + video.pause(); + } + } +} + +onload = runTest; +</script> +</body> +</html> diff --git a/dom/media/webvtt/test/mochitest/test_webvtt_event_same_time.html b/dom/media/webvtt/test/mochitest/test_webvtt_event_same_time.html new file mode 100644 index 0000000000..e70ff558e1 --- /dev/null +++ b/dom/media/webvtt/test/mochitest/test_webvtt_event_same_time.html @@ -0,0 +1,63 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset='utf-8'> + <title>WebVTT : cue's onenter/onexit event order </title> + <script type="text/javascript" src="/MochiKit/MochiKit.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<div id="content"> +</div> +<script class="testbody" type="text/javascript"> +SimpleTest.waitForExplicitFinish(); + +var c1exit = false; +var c3enter = false; + +function runTest() { + info("--- create video ---"); + var video = document.createElement("video"); + video.src = "seek.webm"; + video.autoplay = true; + document.getElementById("content").appendChild(video); + + var track = video.addTextTrack("subtitles", "A", "en"); + track.mode = "showing"; + + var cue1 = new VTTCue(1, 2, "Test cue1"); + var cue2 = new VTTCue(2, 3, "Test cue2"); + track.addCue(cue1); + track.addCue(cue2); + + cue1.onexit = function () { + cue1.onexit = null; + c1exit = true; + } + cue2.onenter = function () { + cue2.onenter = null; + ok(c1exit, "cue1 onexit event before than cue2 onenter"); + video.pause(); + SimpleTest.finish(); + } + + var cue3 = new VTTCue(1, 2, "Test cue3"); + var cue4 = new VTTCue(1, 2, "Test cue4"); + track.addCue(cue3); + track.addCue(cue4); + + cue3.onenter = function () { + cue3.onenter = null; + c3enter = true; + } + cue4.onenter = function () { + cue4.onenter = null; + ok(c3enter, "cue3 onenter event before than cue4 onenter"); + } +} + +onload = runTest; +</script> +</body> +</html> diff --git a/dom/media/webvtt/test/mochitest/test_webvtt_infinite_processing_loop.html b/dom/media/webvtt/test/mochitest/test_webvtt_infinite_processing_loop.html new file mode 100644 index 0000000000..c8a9380ca2 --- /dev/null +++ b/dom/media/webvtt/test/mochitest/test_webvtt_infinite_processing_loop.html @@ -0,0 +1,49 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Bug 1580015 - video hangs infinitely during playing subtitle</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="manifest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <style> + .container { + width: 500px; + height: 300px; + background: pink; + display: flex; + justify-content: center; + } + + video { + min-width: 95%; + max-width: 95%; + max-height: 95%; + } + </style> +</head> +<body> +<div class="container"> +<video id="v" src="gizmo.mp4" controls> + <track src="basic.vtt" kind="subtitles" default> +</video> +</div> +<script type="text/javascript"> +/** + * This test is used to ensure that we don't go into an infinite processing loop + * during playing subtitle when setting those CSS properties on video. + */ +SimpleTest.waitForExplicitFinish(); + +let video = document.getElementById("v"); +// We don't need to play whole video, in order to reduce test time, we can start +// from the half, which can also reproduce the issue. +video.currentTime = 3.0; +video.play(); +video.onended = () => { + ok(true, "video ends without entering an infinite processing loop"); + SimpleTest.finish(); +} + +</script> +</body> +</html> diff --git a/dom/media/webvtt/test/mochitest/test_webvtt_overlapping_time.html b/dom/media/webvtt/test/mochitest/test_webvtt_overlapping_time.html new file mode 100644 index 0000000000..5ce08ae77a --- /dev/null +++ b/dom/media/webvtt/test/mochitest/test_webvtt_overlapping_time.html @@ -0,0 +1,100 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>WebVTT : cues with overlapping time should be displayed correctly </title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="manifest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<video id ="v" src="gizmo.mp4" controls> +<script class="testbody" type="text/javascript"> +/** + * This test is used to ensure that when cues with overlapping times, the one + * with earlier end timestamp should disappear when the media time reaches its + * end time. In this test, we have two cues with overlapping time, when the video + * starts, both cues should be displayed. When the time passes 1 seconds, the + * first cue should disappear and the second cues should be still displayed. + */ +var CUES_INFO = [ + { id: 0, startTime: 0, endTime: 1, text: "This is cue 0."}, + { id: 1, startTime: 0, endTime: 6, text: "This is cue 1."}, +]; + +var video = document.getElementById("v"); + +async function startTest() { + const cues = createCues(); + await startVideo(); + + await waitUntilCueIsShowing(cues[0]); + await waitUntilCueIsShowing(cues[1]); + + await waitUntilCueIsHiding(cues[0]); + await waitUntilCueIsShowing(cues[1]); + IsVideoStillPlaying(); + + endTestAndClearVideo(); +} + +SimpleTest.waitForExplicitFinish(); +onload = startTest; + +/** + * The following are test helper functions. + */ +function createCues() { + let track = video.addTextTrack("subtitles"); + track.mode = "showing"; + let cue0 = new VTTCue(CUES_INFO[0].startTime, CUES_INFO[0].endTime, + CUES_INFO[0].text); + cue0.id = CUES_INFO[0].id; + let cue1 = new VTTCue(CUES_INFO[1].startTime, CUES_INFO[1].endTime, + CUES_INFO[1].text); + cue1.id = CUES_INFO[1].id; + track.addCue(cue0); + track.addCue(cue1); + // Convert them to chrome objects in order to use chrome privilege APIs. + cue0 = SpecialPowers.wrap(cue0); + cue1 = SpecialPowers.wrap(cue1); + return [cue0, cue1]; +} + +async function startVideo() { + info(`start play video`); + const played = video && await video.play().then(() => true, () => false); + ok(played, "video has started playing"); +} + +async function waitUntilCueIsShowing(cue) { + info(`wait until cue ${cue.id} is showing`); + // cue has not been showing yet. + if (!cue.getActive) { + await once(cue, "enter"); + } + info(`video current time=${video.currentTime}`); + ok(cue.getActive, `cue ${cue.id} is showing`); +} + +async function waitUntilCueIsHiding(cue) { + info(`wait until cue ${cue.id} is hiding`); + // cue has not been hidden yet. + if (cue.getActive) { + await once(cue, "exit"); + } + info(`video current time=${video.currentTime}`); + ok(!cue.getActive, `cue ${cue.id} is hidding`); +} + +function IsVideoStillPlaying() { + ok(!video.paused, `video is still playing, currentTime=${video.currentTime}`); +} + +function endTestAndClearVideo() { + removeNodeAndSource(video); + SimpleTest.finish(); +} + +</script> +</body> +</html> diff --git a/dom/media/webvtt/test/mochitest/test_webvtt_positionalign.html b/dom/media/webvtt/test/mochitest/test_webvtt_positionalign.html new file mode 100644 index 0000000000..267fd52f93 --- /dev/null +++ b/dom/media/webvtt/test/mochitest/test_webvtt_positionalign.html @@ -0,0 +1,113 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset='utf-8'> + <title>WebVTT : position align test</title> + <script type="text/javascript" src="/MochiKit/MochiKit.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<div id="content"> +</div> +<script class="testbody" type="text/javascript"> +SimpleTest.waitForExplicitFinish(); + +var video = document.createElement("video"); +var trackElement = document.createElement("track"); +var cuesNumber = 22; + +function isTrackElemenLoaded() { + // Re-que isTrackElemenLoaded() at the end of the event loop until the track + // element has loaded its data. + if (trackElement.readyState == 1) { + setTimeout(isTrackElemenLoaded, 0); + return; + } + + is(trackElement.readyState, 2, "Track::ReadyState should be set to LOADED."); + runTest(); +} + +function runTest() { + info("--- check cues number ---"); + var cues = trackElement.track.cues; + is(cues.length, cuesNumber, "Cues number is correct."); + + info("--- check the typedef of TextTrackCue and VTTCue ---"); + isnot(window.TextTrackCue, undefined, "TextTrackCue should be defined."); + isnot(window.VTTCue, undefined, "VTTCue should be defined."); + + info("--- check the type of first parsed cue ---"); + ok(cues[0] instanceof TextTrackCue, "Cue should be an instanceof TextTrackCue."); + ok(cues[0] instanceof VTTCue, "Cue should be an instanceof VTTCue."); + + info("--- check the cue's position alignment ---"); + let expectedAlignment = ["auto", "line-left", "center", "line-right", "auto"]; + let idx = 0; + for (;idx < expectedAlignment.length; idx++) { + is(cues[idx].positionAlign, expectedAlignment[idx], cues[idx].text); + } + + info("--- check the cue's computed position alignment ---"); + // The "computedPositionAlign" is the chrome-only attributes, we need to get + // the chrome privilege for cues. + let cuesChrome = SpecialPowers.wrap(cues); + expectedAlignment.push("line-left", "line-right", "center"); + for (;idx < expectedAlignment.length; idx++) { + is(cuesChrome[idx].computedPositionAlign, expectedAlignment[idx], + cuesChrome[idx].text); + } + + info(`test only setting text alignment with "start"`); + expectedAlignment.push("line-left", "line-right", "line-left", "line-right", + "line-left", "line-left", "line-right"); + for (;idx < expectedAlignment.length; idx++) { + is(cuesChrome[idx].computedPositionAlign, expectedAlignment[idx], + cuesChrome[idx].text); + } + + info(`test only setting text alignment with "end"`); + expectedAlignment.push("line-right", "line-left", "line-right", "line-left", + "line-right", "line-right", "line-left"); + for (;idx < expectedAlignment.length; idx++) { + is(cuesChrome[idx].computedPositionAlign, expectedAlignment[idx], + cuesChrome[idx].text); + } + is(idx, cuesNumber, "finished checking all cues"); + + info("--- check the cue's computed position alignment from DOM API ---"); + is(cuesChrome[0].computedPositionAlign, "center", "Cue's computedPositionAlign align is center."); + + cuesChrome[0].positionAlign = "auto"; + is(cuesChrome[0].positionAlign, "auto", "Change cue's position align to \"auto\""); + + cuesChrome[0].align = "left"; + is(cuesChrome[0].align, "left", "Change cue's align to \"left\"."); + + is(cuesChrome[0].computedPositionAlign, "line-left", "Cue's computedPositionAlign becomes to \"line-left\""); + + info("--- finish test ---"); + SimpleTest.finish(); +} + +function setupTest() { + info("--- setup test ---"); + video.src = "seek.webm"; + video.preload = "auto"; + + trackElement.src = "vttPositionAlign.vtt"; + trackElement.kind = "subtitles"; + trackElement.default = true; + + document.getElementById("content").appendChild(video); + video.appendChild(trackElement); + video.addEventListener("loadedmetadata", function() { + isTrackElemenLoaded(); + }, {once: true}); +} + +onload = setupTest; +</script> +</body> +</html> diff --git a/dom/media/webvtt/test/mochitest/test_webvtt_seeking.html b/dom/media/webvtt/test/mochitest/test_webvtt_seeking.html new file mode 100644 index 0000000000..1f85969743 --- /dev/null +++ b/dom/media/webvtt/test/mochitest/test_webvtt_seeking.html @@ -0,0 +1,110 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>WebVTT : cue should be displayed properly after seeking</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="manifest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<script class="testbody" type="text/javascript"> +/** + * This test is used to ensure that the cue should be showed or hid correctly + * after seeking. In this test, we have two cues which are not overlapped, so + * there should only have one cue showing at a time. + */ +var CUES_INFO = [ + { id: 0, startTime: 1, endTime: 3, text: "This is cue 0."}, + { id: 1, startTime: 4, endTime: 6, text: "This is cue 1."}, +]; + +async function startTest() { + const video = createVideo(); + const cues = createCues(video); + await startVideo(video); + + await seekVideo(video, cues[0].startTime); + await waitUntilCueIsShowing(cues[0]); + checkActiveCueAndInactiveCue(cues[0], cues[1]); + + await seekVideo(video, cues[1].startTime); + await waitUntilCueIsShowing(cues[1]); + checkActiveCueAndInactiveCue(cues[1], cues[0]); + + // seek forward again + await seekVideo(video, cues[0].startTime); + await waitUntilCueIsShowing(cues[0]); + checkActiveCueAndInactiveCue(cues[0], cues[1]); + + removeNodeAndSource(video); + SimpleTest.finish(); +} + +SimpleTest.waitForExplicitFinish(); +onload = startTest; +/** + * The following are test helper functions. + */ +function checkActiveCueAndInactiveCue(activeCue, inactiveCue) { + ok(activeCue.getActive, + `cue ${activeCue.id} [${activeCue.startTime}:${activeCue.endTime}] is active`); + ok(!inactiveCue.getActive, + `cue ${inactiveCue.id} [${inactiveCue.startTime}:${inactiveCue.endTime}] is inactive`); +} + +function createVideo() { + let video = document.createElement("video"); + video.src = "gizmo.mp4"; + video.controls = true; + document.body.appendChild(video); + return video; +} + +function createCues(video) { + let track = video.addTextTrack("subtitles"); + track.mode = "showing"; + let cue0 = new VTTCue(CUES_INFO[0].startTime, CUES_INFO[0].endTime, + CUES_INFO[0].text); + cue0.id = CUES_INFO[0].id; + let cue1 = new VTTCue(CUES_INFO[1].startTime, CUES_INFO[1].endTime, + CUES_INFO[1].text); + cue1.id = CUES_INFO[1].id; + track.addCue(cue0); + track.addCue(cue1); + // Convert them to chrome objects in order to use chrome privilege APIs. + cue0 = SpecialPowers.wrap(cue0); + cue1 = SpecialPowers.wrap(cue1); + return [cue0, cue1]; +} + +async function startVideo(video) { + info(`start play video`); + const played = video && await video.play().then(() => true, () => false); + ok(played, "video has started playing"); +} + +async function waitUntilCueIsShowing(cue) { + info(`wait until cue ${cue.id} shows`); + // cue has not been showing yet. + if (!cue.getActive) { + await once(cue, "enter"); + } + info(`cue ${cue.id} is showing`); +} + +async function seekVideo(video, time) { + ok(isInRange(time, CUES_INFO[0].startTime, CUES_INFO[0].endTime) || + isInRange(time, CUES_INFO[1].startTime, CUES_INFO[1].endTime), + `seek target time ${time} is within the correct range`) + info(`seek video to ${time}`); + video.currentTime = time; + await once(video, "seeked"); + info(`seek succeeded, current time=${video.currentTime}`); +} + +function isInRange(value, lowerBound, higherBound) { + return lowerBound <= value && value <= higherBound; +} +</script> +</body> +</html> diff --git a/dom/media/webvtt/test/mochitest/test_webvtt_update_display_after_adding_or_removing_cue.html b/dom/media/webvtt/test/mochitest/test_webvtt_update_display_after_adding_or_removing_cue.html new file mode 100644 index 0000000000..7fb8e6761b --- /dev/null +++ b/dom/media/webvtt/test/mochitest/test_webvtt_update_display_after_adding_or_removing_cue.html @@ -0,0 +1,93 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>WebVTT : cue display should be updated immediately after adding or removing cue</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="manifest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<script class="testbody" type="text/javascript"> +/** + * This test is used to ensure that we will update cue display immediately after + * adding or removing cue after video starts, because `show-poster` flag would be + * reset after video starts, which allows us to process cues instead of showing + * a poster. In this test, we start with adding a cue [0:5] to video, which + * should be showed in the beginning, and then remove the cue later. The cue + * should be removed immediately, not show + */ +async function startTest() { + const video = await createVideo(); + await startVideo(video); + + info(`cue should be showed immediately after it was added.`); + const cue = createCueAndAddCueToVideo(video); + await waitUntilCueShows(cue); + + info(`cue should be hid immediately after it was removed.`); + removeCueFromVideo(cue, video); + checkIfCueHides(cue, video); + + endTestAndClearVideo(video); +} + +SimpleTest.waitForExplicitFinish(); +onload = startTest; + +/** + * The following are test helper functions. + */ +async function createVideo() { + let video = document.createElement("video"); + video.src = "gizmo.mp4"; + video.controls = true; + document.body.appendChild(video); + // wait until media has loaded any data, because we won't update cue if it has + // not got any data. + await once(video, "loadedmetadata"); + return video; +} + +async function startVideo(video) { + info(`start play video`); + const played = video && await video.play().then(() => true, () => false); + ok(played, "video has started playing"); +} + +function createCueAndAddCueToVideo(video) { + let track = video.addTextTrack("subtitles"); + track.mode = "showing"; + let cue = new VTTCue(0, 5, "Test"); + track.addCue(cue); + return cue; +} + +function removeCueFromVideo(cue, video) { + let track = video.textTracks[0]; + track.removeCue(cue); +} + +async function waitUntilCueShows(cue) { + info(`wait until cue shows`); + // cue has not been showed yet. + cue = SpecialPowers.wrap(cue); + if (!cue.getActive) { + await once(cue, "enter"); + } + ok(cue.getActive, `cue has been showed,`); +} + +function checkIfCueHides(cue, video) { + ok(!SpecialPowers.wrap(cue).getActive, `cue has been hidden.`); + ok(video.currentTime < cue.endTime, + `cue is removed at ${video.currentTime}s before reaching its endtime.`); +} + +function endTestAndClearVideo(video) { + removeNodeAndSource(video); + SimpleTest.finish(); +} + +</script> +</body> +</html> diff --git a/dom/media/webvtt/test/mochitest/vttPositionAlign.vtt b/dom/media/webvtt/test/mochitest/vttPositionAlign.vtt new file mode 100644 index 0000000000..7613f4e7c5 --- /dev/null +++ b/dom/media/webvtt/test/mochitest/vttPositionAlign.vtt @@ -0,0 +1,86 @@ +WEBVTT + +00:00.000 --> 00:00.500 +Cue 0 : PositionAlign should be "auto". + +00:00.700 --> 00:00.800 position:50%,line-left +Cue 1 : PositionAlign should be "line-left". + +00:00.700 --> 00:00.800 position:50%,center +Cue 2 : PositionAlign should be "center". + +00:00.700 --> 00:00.800 position:50%,line-right +Cue 3 : PositionAlign should be "line-right". + +00:00.700 --> 00:00.800 position:50%,auto +Cue 4 : PositionAlign should be "auto" + +00:00.700 --> 00:00.800 position:50%,auto align:left +Cue 5 : PositionAlign should be "auto", but computedPositionAlign should be "line-left". + +00:00.700 --> 00:00.800 position:50%,auto align:right +Cue 6 : PositionAlign should be "auto", but computedPositionAlign should be "line-right". + +00:00.700 --> 00:00.800 position:50%,auto align:middle +Cue 7 : PositionAlign should be "auto", but computedPositionAlign should be "center". + +NOTE ### These following cues are set with `align:start` ### + +00:00.700 --> 00:00.800 align:start +LTR character in the beginning and align is "start", so computedPositionAlign should be "line-left". + +00:00.700 --> 00:00.800 align:start +שלום RTL character in the beginning and align is "start", so computedPositionAlign should be "line-right". + +00:00.700 --> 00:00.800 align:start +@ neutral charater in the beginning, but the first strong charater is LTR in "align:start". So computedPositionAlign should be "line-left". + +00:00.700 --> 00:00.800 align:start +@ש neutral charater in the beginning, but the first strong charater is RTL in "align:start". So computedPositionAlign should be "line-right". + +NOTE +This line contains only neutral charater, we would treat its base direction as +LTR. However, if there are other following lines contains non-neutral +charaters, we would detemine the base direction by the following line. + +00:00.700 --> 00:00.800 align:start +@ + +00:00.700 --> 00:00.800 align:start +@ +The second line starts with LTR charater, computedPositionAlign should be "line-left". + +00:00.700 --> 00:00.800 align:start +@ +שThe second line starts with RTL charater, computedPositionAlign should be "line-right". + +NOTE ### These following cues are set with `align:end` ### + +00:00.700 --> 00:00.800 align:end +LTR character in the beginning and align is "end", so computedPositionAlign should be "line-right". + +00:00.700 --> 00:00.800 align:end +ש RTL character in the beginning and align is "end", so computedPositionAlign should be "line-left". + +00:00.700 --> 00:00.800 align:end +@ neutral charater in the beginning, but the first strong charater is LTR in "align:end". So computedPositionAlign should be "line-right". + +00:00.700 --> 00:00.800 align:end +@ש neutral charater in the beginning, but the first strong charater is RTL in "align:end". So computedPositionAlign should be "line-left". + +NOTE +This line contains only neutral charater, we would treat its base direction as +LTR. However, if there are other following lines contains non-neutral +charaters, we would detemine the base direction by the following line. + +00:00.700 --> 00:00.800 align:end +@ + +00:00.700 --> 00:00.800 align:end +@ +The second line starts with LTR charater, computedPositionAlign should be "line-right". + +00:00.700 --> 00:00.800 align:end +@ +שThe second line starts with RTL charater, computedPositionAlign should be "line-left". + diff --git a/dom/media/webvtt/test/reftest/black.mp4 b/dom/media/webvtt/test/reftest/black.mp4 Binary files differnew file mode 100644 index 0000000000..24eb3be139 --- /dev/null +++ b/dom/media/webvtt/test/reftest/black.mp4 diff --git a/dom/media/webvtt/test/reftest/cues_time_overlapping.webvtt b/dom/media/webvtt/test/reftest/cues_time_overlapping.webvtt new file mode 100644 index 0000000000..8ed899a9d8 --- /dev/null +++ b/dom/media/webvtt/test/reftest/cues_time_overlapping.webvtt @@ -0,0 +1,7 @@ +WEBVTT FILE + +00:00:00.000 --> 00:00:01.000 +First cue + +00:00:00.000 --> 00:00:04.000 +Second cue diff --git a/dom/media/webvtt/test/reftest/reftest.list b/dom/media/webvtt/test/reftest/reftest.list new file mode 100644 index 0000000000..8311bac10f --- /dev/null +++ b/dom/media/webvtt/test/reftest/reftest.list @@ -0,0 +1,3 @@ +skip-if(Android) fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu)&&/^aarch64-msvc/.test(xulRuntime.XPCOMABI),0-136,0-427680) == vtt_update_display_after_removed_cue.html vtt_update_display_after_removed_cue_ref.html +skip-if(Android) fuzzy-if(winWidget,0-170,0-170) == vtt_overlapping_time.html vtt_overlapping_time-ref.html +skip-if(Android) != vtt_reflow_display.html vtt_reflow_display-ref.html diff --git a/dom/media/webvtt/test/reftest/vtt_overlapping_time-ref.html b/dom/media/webvtt/test/reftest/vtt_overlapping_time-ref.html new file mode 100644 index 0000000000..a44e24678b --- /dev/null +++ b/dom/media/webvtt/test/reftest/vtt_overlapping_time-ref.html @@ -0,0 +1,29 @@ +<!DOCTYPE HTML> +<html class="reftest-wait"> +<head> +</head> +<body> +<video id="v1" src="black.mp4" width="320" height="180"> + <track label="English" src="cues_time_overlapping.webvtt" default> +</video> +<script type="text/javascript"> +/** + * This test is to ensure that when cues with overlapping times, the one with + * earlier end timestamp should disappear when the media time reaches its + * end time. This vtt file contains two cues, the first cue is [0,1], the second + * cue is [0,4], so if we seek video to 2s, only cue2 should be displayed. + */ +async function testTimeOverlappingCues() { + const video = document.getElementById("v1"); + video.currentTime = 2; + video.onseeked = () => { + video.onseeked = null; + document.documentElement.removeAttribute('class'); + } +}; + +window.addEventListener("MozReftestInvalidate", + testTimeOverlappingCues); +</script> +</body> +</html> diff --git a/dom/media/webvtt/test/reftest/vtt_overlapping_time.html b/dom/media/webvtt/test/reftest/vtt_overlapping_time.html new file mode 100644 index 0000000000..f973b398d5 --- /dev/null +++ b/dom/media/webvtt/test/reftest/vtt_overlapping_time.html @@ -0,0 +1,30 @@ +<!DOCTYPE HTML> +<html class="reftest-wait"> +<head> +</head> +<body> +<video id="v1" src="black.mp4" autoplay width="320" height="180"> + <track label="English" src="cues_time_overlapping.webvtt" default> +</video> +<script type="text/javascript"> +/** + * This test is to ensure that when cues with overlapping times, the one with + * earlier end timestamp should disappear when the media time reaches its + * end time. This vtt file contains two cues, the first cue is [0,1], the second + * cue is [0,4], so after video is playing over 1s, only cue2 should be displayed. + */ +async function testTimeOverlappingCues() { + const video = document.getElementById("v1"); + video.ontimeupdate = () => { + if (video.currentTime > 1.0) { + document.documentElement.removeAttribute('class'); + video.ontimeupdate = null; + } + } +}; + +window.addEventListener("MozReftestInvalidate", + testTimeOverlappingCues); +</script> +</body> +</html> diff --git a/dom/media/webvtt/test/reftest/vtt_reflow_display-ref.html b/dom/media/webvtt/test/reftest/vtt_reflow_display-ref.html new file mode 100644 index 0000000000..19f3208e6b --- /dev/null +++ b/dom/media/webvtt/test/reftest/vtt_reflow_display-ref.html @@ -0,0 +1,28 @@ +<!DOCTYPE HTML> +<html> +<link rel="stylesheet" href="vtt_reflow_display.css"> +<body> +<div class="video-player"> + <div class="video-layer"> + <video id="v1" autoplay controls></video> + </div> +</div> +<script> +/** + * Simply play and pause a video without any cues. + */ +async function testDisplayCueDuringFrequentReflowRef() { + const video = document.getElementById("v1"); + video.src = "white.webm"; + video.onplay = _ => { + video.onplay = null; + video.pause(); + document.documentElement.removeAttribute('class'); + } +}; + +window.addEventListener("MozReftestInvalidate", + testDisplayCueDuringFrequentReflowRef); +</script> +</body> +</html> diff --git a/dom/media/webvtt/test/reftest/vtt_reflow_display.css b/dom/media/webvtt/test/reftest/vtt_reflow_display.css new file mode 100644 index 0000000000..4b66a07bd4 --- /dev/null +++ b/dom/media/webvtt/test/reftest/vtt_reflow_display.css @@ -0,0 +1,33 @@ +body { + display: flex; + flex-direction: column; + align-items: center; + max-height: 100%; + width: 100vw; + height: 100vh; +} +.video-player { + display: flex; + max-height: calc(100% - 400px); + flex: 1 1 0; + flex-direction: column; + position: relative; + max-width: 100%; + height: 0; +} +.video-layer { + position: relative; + display: flex; + flex-direction: column; + width: 100%; + height: 100%; + flex: 1 1 0; +} +video { + object-fit: contain; + display: flex; + flex: auto; + max-width: 100%; + min-height: 0; + min-width: 0; +} diff --git a/dom/media/webvtt/test/reftest/vtt_reflow_display.html b/dom/media/webvtt/test/reftest/vtt_reflow_display.html new file mode 100644 index 0000000000..e7ec496bc1 --- /dev/null +++ b/dom/media/webvtt/test/reftest/vtt_reflow_display.html @@ -0,0 +1,37 @@ +<!DOCTYPE HTML> +<html class="reftest-wait"> +<head> +</head> +<link rel="stylesheet" href="vtt_reflow_display.css"> +<body> +<div class="video-player"> + <div class="video-layer"> + <video id="v1" autoplay controls></video> + </div> +</div> +<script> +/** + * In bug 1733232, setting some CSS properties (from bug 1733232 comment17) + * would cause video frame's reflow called very frequently, which crashed the + * video control and caused no cue showing. We compare this test with another + * white video without any cues, and they should NOT be equal. + */ +function testDisplayCueDuringFrequentReflow() { + let video = document.getElementById("v1"); + video.src = "white.webm"; + let cue = new VTTCue(0, 4, "hello testing"); + cue.onenter = _ => { + cue.onenter = null; + video.pause(); + document.documentElement.removeAttribute('class'); + } + let track = video.addTextTrack("captions"); + track.mode = "showing"; + track.addCue(cue); +}; + +window.addEventListener("MozReftestInvalidate", + testDisplayCueDuringFrequentReflow); +</script> +</body> +</html> diff --git a/dom/media/webvtt/test/reftest/vtt_update_display_after_removed_cue.html b/dom/media/webvtt/test/reftest/vtt_update_display_after_removed_cue.html new file mode 100644 index 0000000000..4cd5d5bbd2 --- /dev/null +++ b/dom/media/webvtt/test/reftest/vtt_update_display_after_removed_cue.html @@ -0,0 +1,36 @@ +<!DOCTYPE HTML> +<html class="reftest-wait"> +<head> +</head> +<body> +<video id="v1" autoplay></video> +<script type="text/javascript"> + +/** + * This test is used to ensure we would update the cue display after removing + * cue from the text track, the removed cue should not display on the video's + * rendering area. + */ +function testUpdateDisplayAfterRemovedCue() { + let video = document.getElementById("v1"); + video.src = "black.mp4"; + let cue = new VTTCue(0, 4, "hello testing"); + let track = video.addTextTrack("captions"); + track.mode = "showing"; + track.addCue(cue); + cue.onenter = () => { + cue.onenter = null; + track.removeCue(cue); + video.pause(); + video.onpause = () => { + video.onpause = null; + document.documentElement.removeAttribute('class'); + } + } +}; + +window.addEventListener("MozReftestInvalidate", + testUpdateDisplayAfterRemovedCue); +</script> +</body> +</html> diff --git a/dom/media/webvtt/test/reftest/vtt_update_display_after_removed_cue_ref.html b/dom/media/webvtt/test/reftest/vtt_update_display_after_removed_cue_ref.html new file mode 100644 index 0000000000..0b1afdc568 --- /dev/null +++ b/dom/media/webvtt/test/reftest/vtt_update_display_after_removed_cue_ref.html @@ -0,0 +1,6 @@ +<!DOCTYPE HTML> +<html> +<body> +<video id="v1" src="black.mp4"></video> +</body> +</html> diff --git a/dom/media/webvtt/test/reftest/white.webm b/dom/media/webvtt/test/reftest/white.webm Binary files differnew file mode 100644 index 0000000000..bbacad7ffd --- /dev/null +++ b/dom/media/webvtt/test/reftest/white.webm diff --git a/dom/media/webvtt/test/xpcshell/test_parser.js b/dom/media/webvtt/test/xpcshell/test_parser.js new file mode 100644 index 0000000000..5ae70f9762 --- /dev/null +++ b/dom/media/webvtt/test/xpcshell/test_parser.js @@ -0,0 +1,158 @@ +"use strict"; + +const { WebVTT } = ChromeUtils.importESModule( + "resource://gre/modules/vtt.sys.mjs" +); + +let fakeWindow = { + /* eslint-disable object-shorthand */ + VTTCue: function () {}, + VTTRegion: function () {}, + /* eslint-enable object-shorthand */ +}; + +// We have a better parser check in WPT. Here I want to check that incomplete +// lines are correctly parsable. +let tests = [ + // Signature + { input: ["WEBVTT"], cue: 0, region: 0 }, + { input: ["", "WE", "BVT", "T"], cue: 0, region: 0 }, + { input: ["WEBVTT - This file has no cues."], cue: 0, region: 0 }, + { input: ["WEBVTT", " - ", "This file has no cues."], cue: 0, region: 0 }, + + // Body with IDs + { + input: [ + "WEB", + "VTT - This file has cues.\n", + "\n", + "14\n", + "00:01:14", + ".815 --> 00:0", + "1:18.114\n", + "- What?\n", + "- Where are we now?\n", + "\n", + "15\n", + "00:01:18.171 --> 00:01:20.991\n", + "- T", + "his is big bat country.\n", + "\n", + "16\n", + "00:01:21.058 --> 00:01:23.868\n", + "- [ Bat", + "s Screeching ]\n", + "- They won't get in your hair. They're after the bug", + "s.\n", + ], + cue: 3, + region: 0, + }, + + // Body without IDs + { + input: [ + "WEBVTT - This file has c", + "ues.\n", + "\n", + "00:01:14.815 --> 00:01:18.114\n", + "- What?\n", + "- Where are we now?\n", + "\n", + "00:01:18.171 --> 00:01:2", + "0.991\n", + "- ", + "This is big bat country.\n", + "\n", + "00:01:21.058 --> 00:01:23.868\n", + "- [ Bats S", + "creeching ]\n", + "- They won't get in your hair. They're after the bugs.\n", + ], + cue: 3, + region: 0, + }, + + // Note + { + input: ["WEBVTT - This file has no cues.\n", "\n", "NOTE what"], + cue: 0, + region: 0, + }, + + // Regions - This vtt is taken from a WPT + { + input: [ + "WE", + "BVTT\n", + "\n", + "REGION\n", + "id:0\n", + "\n", + "REGION\n", + "id:1\n", + "region", + "an", + "chor:0%,0%\n", + "\n", + "R", + "EGION\n", + "id:2\n", + "regionanchor:18446744073709552000%,18446744", + "073709552000%\n", + "\n", + "REGION\n", + "id:3\n", + "regionanchor: 100%,100%\n", + "regio", + "nanchor :100%,100%\n", + "regionanchor:100% ,100%\n", + "regionanchor:100%, 100%\n", + "regionanchor:100 %,100%\n", + "regionanchor:10", + "0%,100 %\n", + "\n", + "00:00:00.000 --> 00:00:01.000", + " region:0\n", + "text\n", + "\n", + "00:00:00.000 --> 00:00:01.000 region:1\n", + "text\n", + "\n", + "00:00:00.000 --> 00:00:01.000 region:3\n", + "text\n", + ], + cue: 3, + region: 4, + }, +]; + +function run_test() { + tests.forEach(test => { + let parser = new WebVTT.Parser(fakeWindow, null); + ok(!!parser, "Ok... this is a good starting point"); + + let cue = 0; + parser.oncue = () => { + ++cue; + }; + + let region = 0; + parser.onregion = () => { + ++region; + }; + + parser.onparsingerror = () => { + ok(false, "No error accepted"); + }; + + test.input.forEach(input => { + parser.parse(new TextEncoder().encode(input)); + }); + + parser.flush(); + + equal(cue, test.cue, "Cue value matches"); + equal(region, test.region, "Region value matches"); + }); +} diff --git a/dom/media/webvtt/test/xpcshell/xpcshell.ini b/dom/media/webvtt/test/xpcshell/xpcshell.ini new file mode 100644 index 0000000000..07aa5d80d8 --- /dev/null +++ b/dom/media/webvtt/test/xpcshell/xpcshell.ini @@ -0,0 +1,3 @@ +[DEFAULT] + +[test_parser.js] |