<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Testing ICE candidates with audio and video tracks</title>
        <script src="../resources/testharness.js"></script>
        <script src="../resources/testharnessreport.js"></script>
    </head>
    <body>
        <script>
promise_test((test) => {
    if (window.testRunner)
        testRunner.setUserMediaPermission(true);

    return navigator.mediaDevices.getUserMedia({audio: true, video: true}).then((stream) => {
        return new Promise((resolve, reject) => {
            var pc = new RTCPeerConnection();
            pc.addTrack(stream.getAudioTracks()[0], stream);
    	    pc.addTrack(stream.getVideoTracks()[0], stream); 
            var candidates = [];
            pc.onicecandidate = (event) => {
                if (event.candidate === null) {
                    resolve(candidates);
                    return;
                }
                candidates.push(event.candidate.candidate);
            };
            pc.createOffer().then((offer) => {
                pc.setLocalDescription(offer);
            });
         });
     }).then((candidates) => {
         var index0Count, index1Count;
         for (var candidate of candidates) {
             if (candidate.sdpMLineIndex === 0)
                 index0Count++;
             if (candidate.sdpMLineIndex === 1)
                 index1Count++;
         }
         assert_true(!!candidates.length, "candidates should be found");
         assert_equals(index0Count, index1Count, "same number of candidates should be found for audio and video");
     });
}, "Basic audio/video ICE candidate gathering");
        </script>
    </body>
</html>
