<!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').srcObject = 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(1);
    }
    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(1);
      })
      .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(type) {
  var videoSize = 0;
  var emptyBlobs = 0;
  var timeStamps = [];

  if (!MediaRecorder.isTypeSupported(type)) {
    // If the MIME type is not supported, there's nothing needed to test.
    // Mark as success.
    reportTestSuccess();
    return;
  }

  navigator.mediaDevices.getUserMedia(DEFAULT_CONSTRAINTS)
      .then(function(stream) {
        return createAndStartMediaRecorder(stream, 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() + " MIME type: " + type);
      })
      .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(1)}, '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(1)}, 'Calling start(1) 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 AudioContext();
  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(1);
        oscillator.start();
      })
      .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(1);
        // 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(1);
        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>
