<!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`));

[
 {width: {max: 360}},
 {height: {max: 240}},
 {width: {max: 360}, height: {max: 240}},
 {frameRate: {max: 4}},
 {frameRate: {max: 4}, width: {max: 360}},
 {frameRate: {max: 4}, height: {max: 240}},
 {frameRate: {max: 4}, width: {max: 360}, height: {max: 240}},
].forEach(constraints => promise_test(async t => {
  const stream = await getDisplayMedia({video: 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({video: ${j(constraints)}}) must be constrained`));

const someSizes = [
 {width: 160},
 {height: 120},
 {width: 80},
 {height: 60},
 {width: 158},
 {height: 118},
];

someSizes.forEach(constraints => promise_test(async t => {
  const stream = await getDisplayMedia({video: constraints});
  t.add_cleanup(() => stopTracks(stream));
  const {width, height, frameRate} = stream.getTracks()[0].getSettings();
  if (constraints.width) {
    assert_equals(width, constraints.width);
  } else {
    assert_equals(height, constraints.height);
  }
  assert_greater_than_equal(frameRate, 1);
}, `getDisplayMedia({video: ${j(constraints)}}) must be downscaled precisely`));

promise_test(async t => {
  const video = {height: 240};
  const stream = await getDisplayMedia({video});
  t.add_cleanup(() => stopTracks(stream));
  const [track] = stream.getVideoTracks();
  const {height} = track.getSettings();
  assert_equals(height, video.height);
  for (const constraints of someSizes) {
    await track.applyConstraints(constraints);
    const {width, height} = track.getSettings();
    if (constraints.width) {
      assert_equals(width, constraints.width);
    } else {
      assert_equals(height, constraints.height);
    }
  }
}, `applyConstraints(width or height) must downscale precisely`);

[
 {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>
