<!DOCTYPE html>
<html>
<head>
<title>MediaStream Recoder Cros Test (w/ MediaSource)</title>
</head>
<body>
  <div> Record Real-Time video content browser test.</div>
  <video id="video" autoplay></video>
</body>
<script type="text/javascript" src="mediarecorder_test_utils.js"></script>
<script>

'use strict';

// The testcases are identical to the media recorder content browser test.
// Helper functions like failTest etc are implemented so they map to the
// CrOS test environment.

// Begin cros related code.

var testProgress = 0;
var result;

function failTest(reason) {
  result = 'FAIL: ' + reason;
  console.log('Test Failed:', reason);
  testProgress = 1;
  // Cause test termination.
  throw reason;
}

function reportTestSuccess() {
  result = 'PASS';
  console.log('Test Passed');
  testProgress = 1;
}

function assertEquals(expected, actual) {
  if (actual != expected)
    failTest("expected '" + expected + "', got '" + actual + "'.");
}

function assertTrue(booleanExpression, reason) {
  if (!booleanExpression)
    failTest(reason);
}

// End cros related code.

const DEFAULT_CONSTRAINTS = {audio: true, video: true};
const DEFAULT_RECORDER_MIME_TYPE = '';
const DEFAULT_TIME_SLICE = 100;
const FREQUENCY = 880;
// Note that not all audio sampling rates are supported by the underlying
// Opus audio codec: the valid rates are 8kHz, 12kHz, 16kHz, 24kHz, 48kHz.
// See crbug/569089 for details.
const SAMPLING_RATE = 48000;
const NUM_SAMPLES = 2 * SAMPLING_RATE;

// Function assert_throws inspired from Blink's
// LayoutTests/resources/testharness.js

function assertThrows(func, description) {
  try {
    func.call(this);
    failTest('Error:' + func + description + ' did not throw!');
  } catch (e) {
    console.log(e);
    reportTestSuccess();
  }
}

function createAndStartMediaRecorder(stream, mimeType, slice) {
  return new Promise(function(resolve, reject) {
    document.getElementById('video').src = URL.createObjectURL(stream);
    var recorder = new MediaRecorder(stream, {'mimeType' : mimeType});
    console.log('Recorder object created.');
    if (slice != undefined) {
      recorder.start(slice);
      console.log('Recorder started with time slice', slice);
    } else {
      recorder.start();
    }
    resolve(recorder);
  });
}

function createMediaRecorder(stream, mimeType) {
  return new Promise(function(resolve, reject) {
    var recorder = new MediaRecorder(stream, {'mimeType' : mimeType});
    console.log('Recorder object created.');
    resolve(recorder);
  });
}

// Tests that the MediaRecorder's start() function will cause the |state| to be
// 'recording' and that a 'start' event is fired.
function testStartAndRecorderState() {
  var startEventReceived = false;
  navigator.mediaDevices.getUserMedia(DEFAULT_CONSTRAINTS)
      .then(function(stream) {
        return createMediaRecorder(stream, DEFAULT_RECORDER_MIME_TYPE);
      })
      .then(function(recorder) {
        recorder.onstart = function(event) {
          startEventReceived = true;
          assertEquals('recording', recorder.state);
        };
        recorder.start();
      })
      .then(function() {
        return waitFor('Make sure the start event was received',
            function() {
              return startEventReceived;
            });
      })
      .catch(function(err) {
        return failTest(err.toString());
      })
      .then(function() {
        reportTestSuccess();
      });
}

// Tests that the MediaRecorder's stop() function will effectively cause the
// |state| to be 'inactive' and that a 'stop' event is fired.
function testStartStopAndRecorderState() {
  var stopEventReceived = false;
  navigator.mediaDevices.getUserMedia(DEFAULT_CONSTRAINTS)
      .then(function(stream) {
        return createAndStartMediaRecorder(stream, DEFAULT_RECORDER_MIME_TYPE);
      })
      .then(function(recorder) {
        recorder.onstop = function(event) {
          stopEventReceived = true;
          assertEquals('inactive', recorder.state);
        };
        recorder.stop();
      })
      .then(function() {
        return waitFor('Make sure the stop event was received',
            function() {
              return stopEventReceived;
            });
      })
      .catch(function(err) {
        return failTest(err.toString());
      })
      .then(function() {
        reportTestSuccess();
      });
}

// Tests that when MediaRecorder's start() function is called, some data is
// made available by media recorder via dataavailable events, containing non
// empty blob data.
function testStartAndDataAvailable() {
  var videoSize = 0;
  var emptyBlobs = 0;
  var timeStamps = [];
  navigator.mediaDevices.getUserMedia(DEFAULT_CONSTRAINTS)
      .then(function(stream) {
        return createAndStartMediaRecorder(stream, DEFAULT_RECORDER_MIME_TYPE);
      })
      .then(function(recorder) {
        // Save history of Blobs received via dataavailable.
        recorder.ondataavailable = function(event) {
          timeStamps.push(event.timeStamp);
          if (event.data.size > 0)
            videoSize += event.data.size;
          else
            emptyBlobs += 1;
        };
      })
      .then(function() {
        return waitFor('Make sure the recording has data',
            function() {
              return videoSize > 0;
            });
      })
      .then(function() {
        assertTrue(emptyBlobs == 0, 'Recording has ' + emptyBlobs +
            ' empty blobs, there should be no such empty blobs.');
      })
      .catch(function(err) {
        return failTest(err.toString());
      })
      .then(function() {
        reportTestSuccess();
      });
}

// Tests that when MediaRecorder's start(timeSlice) is called, some data
// available events are fired containing non empty blob data.
function testStartWithTimeSlice() {
  var videoSize = 0;
  var emptyBlobs = 0;
  var timeStamps = [];
  navigator.mediaDevices.getUserMedia(DEFAULT_CONSTRAINTS)
      .then(function(stream) {
        return createAndStartMediaRecorder(stream, DEFAULT_RECORDER_MIME_TYPE,
            DEFAULT_TIME_SLICE);
      })
      .then(function(recorder) {
        recorder.ondataavailable = function(event) {
          timeStamps.push(event.timeStamp);
          if (event.data.size > 0)
            videoSize += event.data.size;
          else
            emptyBlobs += 1;
        };
      })
      .then(function() {
        return waitFor('Making sure the recording has data',
            function() {
              return videoSize > 0 && timeStamps.length > 10;
            });
      })
      .then(function() {
        assertTrue(emptyBlobs == 0, 'Recording has ' + emptyBlobs +
            ' empty blobs, there should be no such empty blobs.');
      })
      .catch(function(err) {
        return failTest(err.toString());
      })
      .then(function() {
        reportTestSuccess();
      });
}


// Tests that when a MediaRecorder's resume() is called, the |state| is
// 'recording' and a 'resume' event is fired.
function testResumeAndRecorderState() {
  var theRecorder;
  var resumeEventReceived = false;
  navigator.mediaDevices.getUserMedia(DEFAULT_CONSTRAINTS)
      .then(function(stream) {
        return createAndStartMediaRecorder(stream, DEFAULT_RECORDER_MIME_TYPE);
      })
      .then(function(recorder) {
        theRecorder = recorder;
        theRecorder.pause();
      })
      .then(function() {
        theRecorder.onresume = function(event) {
          resumeEventReceived = true;
          assertEquals('recording', theRecorder.state);
        };
        theRecorder.resume();
      })
      .then(function() {
        return waitFor('Making sure the resume event has been received',
            function() {
              return resumeEventReceived;
            });
      })
      .catch(function(err) {
        return failTest(err.toString());
      })
      .then(function() {
        reportTestSuccess();
      });
}

// Tests that is it not possible to resume an inactive MediaRecorder.
function testIllegalResumeThrowsDOMError() {
  navigator.mediaDevices.getUserMedia(DEFAULT_CONSTRAINTS)
      .then(function(stream) {
        return createMediaRecorder(stream, DEFAULT_RECORDER_MIME_TYPE);
      })
      .then(function(recorder) {
        assertThrows(function() {recorder.resume()}, 'Calling resume() in' +
            ' inactive state should cause a DOM error');
      });
}

// Tests that MediaRecorder sends data blobs when resume() is called.
function testResumeAndDataAvailable() {
  var videoSize = 0;
  var emptyBlobs = 0;
  navigator.mediaDevices.getUserMedia(DEFAULT_CONSTRAINTS)
      .then(function(stream) {
        return createAndStartMediaRecorder(stream, DEFAULT_RECORDER_MIME_TYPE);
      })
      .then(function(recorder) {
        recorder.pause();
        recorder.ondataavailable = function(event) {
          if (event.data.size > 0) {
            videoSize += event.data.size;
          } else {
            console.log('This dataavailable event is empty', event);
            emptyBlobs += 1;
          }
        };
        recorder.resume();
      })
      .then(function() {
        return waitFor('Make sure the recording has data after resuming',
            function() {
              return videoSize > 0;
            });
      })
      .then(function() {
        // There should be no empty blob while recording.
        assertTrue(emptyBlobs == 0, 'Recording has ' + emptyBlobs +
            ' empty blobs, there should be no such empty blobs.');
      })
      .catch(function(err) {
        return failTest(err.toString());
      })
      .then(function() {
        reportTestSuccess();
      });
}

// Tests that when paused the recorder will transition |state| to |paused| and
// then trigger a |pause| event.
function testPauseAndRecorderState() {
  var pauseEventReceived = false;
  navigator.mediaDevices.getUserMedia(DEFAULT_CONSTRAINTS)
      .then(function(stream) {
        return createAndStartMediaRecorder(stream, DEFAULT_RECORDER_MIME_TYPE);
      })
      .then(function(recorder) {
        recorder.onpause = function(event) {
          pauseEventReceived = true;
          assertEquals('paused', recorder.state);
        };
        recorder.pause();
      })
      .then(function() {
        return waitFor('Making sure the pause event has been received',
            function() {
              return pauseEventReceived;
            });
      })
      .catch(function(err) {
        return failTest(err.toString());
      })
      .then(function() {
        reportTestSuccess();
      });
}

// Tests that is is possible to stop a paused MediaRecorder and that the |state|
// becomes 'inactive'.
function testPauseStopAndRecorderState() {
  navigator.mediaDevices.getUserMedia(DEFAULT_CONSTRAINTS)
      .then(function(stream) {
        return createAndStartMediaRecorder(stream, DEFAULT_RECORDER_MIME_TYPE);
      })
      .then(function(recorder) {
        recorder.pause();
        recorder.stop();
        assertEquals('inactive', recorder.state);
      })
      .catch(function(err) {
        return failTest(err.toString());
      })
      .then(function() {
        reportTestSuccess();
      });
}

// Tests that no dataavailable event is fired after MediaRecorder's pause()
// function is called.
function testPausePreventsDataavailableFromBeingFired() {
  navigator.mediaDevices.getUserMedia(DEFAULT_CONSTRAINTS)
      .then(function(stream) {
        return createAndStartMediaRecorder(stream, DEFAULT_RECORDER_MIME_TYPE);
      })
      .then(function(recorder) {
        recorder.pause();
        recorder.ondataavailable = function(event) {
          failTest('Received unexpected data after pause!');
        };
      })
      .then(function() {
        return waitDuration(2000);
      })
      .catch(function(err) {
        return failTest(err.toString());
      })
      .then(function() {
        reportTestSuccess();
      });
}

// Tests that MediaRecorder's pause() throws an exception if |state| is not
// 'recording'.
function testIllegalPauseThrowsDOMError() {
  navigator.mediaDevices.getUserMedia(DEFAULT_CONSTRAINTS)
      .then(function(stream) {
        return createMediaRecorder(stream, DEFAULT_RECORDER_MIME_TYPE);
      })
      .then(function(recorder) {
        assertThrows(function() {recorder.pause()}, 'Calling pause() in' +
            ' inactive state should cause a DOM error');
      });
}

// Tests that MediaRecorder's stop() throws an exception if |state| is not
// 'recording'.
function testIllegalStopThrowsDOMError() {
  navigator.mediaDevices.getUserMedia(DEFAULT_CONSTRAINTS)
      .then(function(stream) {
        return createMediaRecorder(stream, DEFAULT_RECORDER_MIME_TYPE);
      })
      .then(function(recorder) {
        assertThrows(function() {recorder.stop()}, 'Calling stop() in' +
            ' inactive state should cause a DOM error');
      });
}

// Tests that MediaRecorder's start() throws an exception if |state| is
// 'recording'.
function testIllegalStartInRecordingStateThrowsDOMError() {
  navigator.mediaDevices.getUserMedia(DEFAULT_CONSTRAINTS)
      .then(function(stream) {
        return createAndStartMediaRecorder(stream, DEFAULT_RECORDER_MIME_TYPE);
      })
      .then(function(recorder) {
        assertThrows(function() {recorder.start()}, 'Calling start() in' +
            ' recording state should cause a DOM error');
      });
}

// Tests that MediaRecorder's start() throws an exception if |state| is
// 'paused'.
function testIllegalStartInPausedStateThrowsDOMError() {
  navigator.mediaDevices.getUserMedia(DEFAULT_CONSTRAINTS)
      .then(function(stream) {
        return createAndStartMediaRecorder(stream, DEFAULT_RECORDER_MIME_TYPE);
      })
      .then(function(recorder) {
        recorder.pause();
        assertThrows(function() {recorder.start()}, 'Calling start() in' +
            ' paused state should cause a DOM error');
      });
}

// Tests that MediaRecorder can record a 2 Channel audio stream.
function testTwoChannelAudio() {
  var audioSize = 0;
  var context = new OfflineAudioContext(2, NUM_SAMPLES, SAMPLING_RATE);
  var oscillator = context.createOscillator();
  oscillator.type = 'sine';
  oscillator.frequency.value = FREQUENCY;
  var dest = context.createMediaStreamDestination();
  dest.channelCount = 2;
  oscillator.connect(dest);
  createMediaRecorder(dest.stream, DEFAULT_RECORDER_MIME_TYPE)
      .then(function(recorder) {
        recorder.ondataavailable = function(event) {
          audioSize += event.data.size;
        };
        recorder.start();
        oscillator.start();
        context.startRendering();
      })
      .then(function() {
        return waitFor('Make sure the recording has data',
            function() {
              return audioSize > 0;
            });
      })
      .catch(function(err) {
        return failTest(err.toString());
      })
      .then(function() {
        console.log('audioSize', audioSize);
        reportTestSuccess();
      });
}

// Tests that MediaRecorder's requestData() throws an exception if |state| is
// 'inactive'.
function testIllegalRequestDataThrowsDOMError() {
  navigator.mediaDevices.getUserMedia(DEFAULT_CONSTRAINTS)
      .then(function(stream) {
        return createMediaRecorder(stream, DEFAULT_RECORDER_MIME_TYPE);
      })
      .then(function(recorder) {
        assertThrows(function() {recorder.requestData()},
            'Calling requestdata() in inactive state should throw a DOM ' +
            'Exception');
      });
}

// Tests that MediaRecorder fires an Error Event when the associated MediaStream
// gets a Track added.
function testAddingTrackToMediaStreamFiresErrorEvent() {
  var theStream;
  var errorEventReceived = false;
  navigator.mediaDevices.getUserMedia(DEFAULT_CONSTRAINTS)
      .then(function(stream) {
        theStream = stream;
        return createMediaRecorder(stream);
      })
      .then(function(recorder) {
        recorder.onerror = function(event) {
          errorEventReceived = true;
        };
        recorder.start();
        // Add a new track, copy of an existing one for simplicity.
        theStream.addTrack(theStream.getTracks()[1].clone());
      })
      .then(function() {
        return waitFor('Waiting for the Error Event',
            function() {
              return errorEventReceived;
            });
      })
      .catch(function(err) {
        return failTest(err.toString());
      })
      .then(function() {
        reportTestSuccess();
      });
}

// Tests that MediaRecorder fires an Error Event when the associated MediaStream
// gets a Track removed.
function testRemovingTrackFromMediaStreamFiresErrorEvent() {
  var theStream;
  var errorEventReceived = false;
  navigator.mediaDevices.getUserMedia(DEFAULT_CONSTRAINTS)
      .then(function(stream) {
        theStream = stream;
        return createMediaRecorder(stream);
      })
      .then(function(recorder) {
        recorder.onerror = function(event) {
          errorEventReceived = true;
        };
        recorder.start();
        theStream.removeTrack(theStream.getTracks()[1]);
      })
      .then(function() {
        return waitFor('Waiting for the Error Event',
            function() {
              return errorEventReceived;
            });
      })
      .catch(function(err) {
        return failTest(err.toString());
      })
      .then(function() {
        reportTestSuccess();
      });
}

</script>
</body>
</html>
