<!doctype html>
<meta charset=utf-8>
<title>getDisplayMedia</title>
<meta name="timeout" content="long">
<button id="button">User gesture</button>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script>
  'use strict';
test(() => {
  assert_idl_attribute(navigator.mediaDevices, 'getDisplayMedia');
}, "getDisplayMedia in navigator.mediaDevices");

const stopTracks = stream => stream.getTracks().forEach(track => track.stop());
const j = obj => JSON.stringify(obj);

async function getDisplayMedia(constraints) {
  const p = new Promise(r => button.onclick = r);
  await test_driver.click(button);
  await p;
  return navigator.mediaDevices.getDisplayMedia(constraints);
}

promise_test(async t => {
  try {
    stopTracks(await navigator.mediaDevices.getDisplayMedia({video: true}));
  } catch (err) {
    assert_equals(err.name, 'InvalidStateError', err.message);
    return;
  }
  assert_unreached('getDisplayMedia should have failed');
}, `getDisplayMedia() must require user activation`);

[
 {video: true},
 {video: true, audio: false},
 {audio: false},
 {audio: true},
 {},
 undefined
].forEach(constraints => promise_test(async t => {
  const stream = await getDisplayMedia(constraints);
  t.add_cleanup(() => stopTracks(stream));
  assert_equals(stream.getTracks().length, 1);
  assert_equals(stream.getVideoTracks().length, 1);
  assert_equals(stream.getAudioTracks().length, 0);
}, `getDisplayMedia(${j(constraints)}) must succeed with video`));

[
 {video: false},
 {video: {advanced: [{width: 320}]}},
 {video: {width: {min: 320}}},
 {video: {width: {exact: 320}}},
 {video: {height: {min: 240}}},
 {video: {height: {exact: 240}}},
 {video: {frameRate: {min: 4}}},
 {video: {frameRate: {exact: 4}}},
 {video: false, audio: true},
].forEach(constraints => promise_test(async t => {
  try {
    stopTracks(await getDisplayMedia(constraints));
  } catch (err) {
    assert_equals(err.name, 'TypeError', err.message);
    return;
  }
  assert_unreached('getDisplayMedia should have failed');
}, `getDisplayMedia(${j(constraints)}) must fail with TypeError`));

[
 {video: true, audio: true},
].forEach(constraints => promise_test(async t => {
  const stream = await getDisplayMedia(constraints);
  t.add_cleanup(() => stopTracks(stream));
  assert_greater_than_equal(stream.getTracks().length, 1);
  assert_less_than_equal(stream.getTracks().length, 2);
  assert_equals(stream.getVideoTracks().length, 1);
  assert_less_than_equal(stream.getAudioTracks().length, 1);
}, `getDisplayMedia(${j(constraints)}) must succeed with video maybe audio`));

[
 {video: {width: {max: 360}}},
 {video: {height: {max: 240}}},
 {video: {width: {max: 360}, height: {max: 240}}},
 {video: {frameRate: {max: 4}}},
 {video: {frameRate: {max: 4}, width: {max: 360}}},
 {video: {frameRate: {max: 4}, height: {max: 240}}},
 {video: {frameRate: {max: 4}, width: {max: 360}, height: {max: 240}}},
].forEach(constraints => promise_test(async t => {
  const stream = await getDisplayMedia(constraints);
  t.add_cleanup(() => stopTracks(stream));
  const {width, height, frameRate} = stream.getTracks()[0].getSettings();
  assert_greater_than_equal(width, 1);
  assert_greater_than_equal(height, 1);
  assert_greater_than_equal(frameRate, 1);
  if (constraints.width) {
    assert_less_than_equal(width, constraints.width.max);
  }
  if (constraints.height) {
    assert_less_than_equal(height, constraints.height.max);
  }
  if (constraints.frameRate) {
    assert_less_than_equal(frameRate, constraints.frameRate.max);
  }
}, `getDisplayMedia(${j(constraints)}) must be constrained`));

[
 {video: {width: {max: 0}}},
 {video: {height: {max: 0}}},
 {video: {frameRate: {max: 0}}},
 {video: {width: {max: -1}}},
 {video: {height: {max: -1}}},
 {video: {frameRate: {max: -1}}},
].forEach(constraints => promise_test(async t => {
  try {
    stopTracks(await getDisplayMedia(constraints));
  } catch (err) {
    assert_equals(err.name, 'OverconstrainedError', err.message);
    return;
  }
  assert_unreached('getDisplayMedia should have failed');
}, `getDisplayMedia(${j(constraints)}) must fail with OverconstrainedError`));

// Content shell picks a fake desktop device by default.
promise_test(async t => {
  const stream = await getDisplayMedia({video: true});
  t.add_cleanup(() => stopTracks(stream));
  assert_equals(stream.getVideoTracks().length, 1);
  const track = stream.getVideoTracks()[0];
  assert_equals(track.kind, "video");
  assert_equals(track.enabled, true);
  assert_equals(track.readyState, "live");
  track.stop();
  assert_equals(track.readyState, "ended");
}, 'getDisplayMedia() resolves with stream with video track');

promise_test(async t => {
  const stream = await getDisplayMedia({video: true});
  t.add_cleanup(() => stopTracks(stream));
  const settings = stream.getVideoTracks()[0].getSettings();
  assert_any(
      assert_equals, settings.displaySurface,
      ['monitor', 'window', 'application', 'browser']);
  assert_any(assert_equals, settings.logicalSurface, [true, false]);
  assert_any(assert_equals, settings.cursor, ['never', 'always', 'motion']);
}, 'getDisplayMedia() with getSettings');

</script>
