<!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(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() {
  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(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 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(1);
        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(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>
