<!DOCTYPE html><!-- webkit-test-runner [ ModernMediaControlsEnabled=false ] -->
<html>
    <head>
        <title>Selecting from a list of tracks</title>
        <script src="media-controls.js"></script>
        <script src="media-file.js"></script>
        <script src="video-test.js"></script>
        <script src="trackmenu-test.js"></script>
        <script>
            if (window.testRunner)
                testRunner.dumpAsText();

            function startTest()
            {
                trackListElement = getTrackListElement();
                if (!trackListElement)
                    return;
                testExpected("trackListElement.offsetHeight", 0, ">");

                consoleWrite("<br>*** Add another text track.");
                run('video.addTextTrack("captions", "Commentary", "ru")');
                showTrackMenu()
                window.setTimeout(turnCaptionsOn, 100);
                consoleWrite("");
            }

            function captionTrackMenuList()
            {
                var trackListElement = getTrackListElement();
                if (!trackListElement)
                    return;
                // Track list should have a <ul> with <li> children (One of them is "Off").
                var trackList = trackListElement.querySelector("ul");
                if (!trackList) {
                    failTest("Could not find a child ul element in track list menu");
                    return;
                }
                var trackListItems = trackList.querySelectorAll("li");
                if (!trackListItems) {
                    failTest("Could not find child li elements in track list menu");
                    return;
                }

                return trackListItems;
            }

            function testMenu()
            {
                trackListItems = captionTrackMenuList();
                var expectedItemCount = video.textTracks.length + 2;
                consoleWrite("There should be " + expectedItemCount + " items in the menu.");
                testExpected("trackListItems.length", expectedItemCount);
            }

            function selectCaptionMenuItem(index, nextStep)
            {
                // Click on the selected item
                var trackListItems = captionTrackMenuList();
                var selectedTrackItem = trackListItems[index];
                var boundingRect = selectedTrackItem.getBoundingClientRect();
                var x = boundingRect.left + boundingRect.width / 2;
                var y = boundingRect.top + boundingRect.height / 2;
                eventSender.mouseMoveTo(x, y);
                eventSender.mouseDown();
                eventSender.mouseUp();
                window.setTimeout(function() { testMenu(); nextStep(); }, 100);
            }

            function turnCaptionsOn()
            {
                consoleWrite("*** Turning captions on");
                // Click on the third item, which is the second track (Off is the first item, Automatic is second)
                selectCaptionMenuItem(3, testCaptionsVisible);
            }

            function testCaptionsVisible()
            {
                testExpected("video.textTracks.length", 4);
                consoleWrite("Track 0 should be showing");
                testExpected("video.textTracks[0].mode", "showing");
                consoleWrite("Track 1 should be disabled");
                testExpected("video.textTracks[1].mode", "disabled");
                consoleWrite("Track 2 should be disabled");
                testExpected("video.textTracks[2].mode", "disabled");
                consoleWrite("Track 3 should be disabled");
                testExpected("video.textTracks[3].mode", "disabled");
                testExpected("textTrackDisplayElement(video, 'display').innerText", "Lorem");

                consoleWrite("<br>*** Remove a track.");
                run('video.removeChild(document.querySelectorAll("track")[0])');

                clickCCButton();
                window.setTimeout(turnCaptionsOff, 100);
            }

            function turnCaptionsOff()
            {
                consoleWrite("*** Turning captions off");
                selectCaptionMenuItem(0, testCaptionsDisabled);
            }

            function testCaptionsDisabled()
            {
                testExpected("video.textTracks.length", 3);
                consoleWrite("Track 0 should be disabled");
                testExpected("video.textTracks[0].mode", "disabled");
                consoleWrite("Track 1 should be disabled");
                testExpected("video.textTracks[1].mode", "disabled");
                consoleWrite("Track 2 should be disabled");
                testExpected("video.textTracks[2].mode", "disabled");
                testExpected("textTrackDisplayElement(video, 'display').innerText", "Lorem");
                endTest();
            }

            function start()
            {
                findMediaElement();
                video.src = findMediaFile('video', 'content/test');
                waitForEvent('canplaythrough', function () { startTrackMenuTest(startTest); });
            }
        </script>
    </head>

    <body onload="start()">
        <p>Test that we are able to trigger the list of captions, and select from the list.</p>
        <video width="500" height="300" controls>
            <track kind="captions" src="track/captions-webvtt/captions-fast.vtt" srclang="fr">
            <track kind="captions" src="track/captions-webvtt/captions-fast.vtt" srclang="en">
            <track kind="captions" src="track/captions-webvtt/captions-fast.vtt" srclang="ja">
        </video>
    </body>
</html>

