<!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(t => {
  const p = navigator.mediaDevices.getDisplayMedia({video: true});
  t.add_cleanup(async () => {
    try { stopTracks(await p) } catch {}
  });
  // Race a settled promise to check that the returned promise is already
  // rejected.
  return promise_rejects_dom(
    t, 'InvalidStateError', Promise.race([p, Promise.resolve()]),
    'getDisplayMedia should have returned an already-rejected promise.');
}, `getDisplayMedia() must require user activation`);

[
 {video: true},
 {video: true, audio: false},
 {video: {}},
 {audio: false},
 {},
 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}}},
].forEach(constraints => promise_test(async t => {
  await test_driver.bless('getDisplayMedia()');
  const p = navigator.mediaDevices.getDisplayMedia(constraints);
  t.add_cleanup(async () => {
    try { stopTracks(await p) } catch {}
  });
  await promise_rejects_js(
    t, TypeError, Promise.race([p, Promise.resolve()]),
    'getDisplayMedia should have returned an already-rejected promise.');
}, `getDisplayMedia(${j(constraints)}) must fail with TypeError`));

[
 {video: true, audio: 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`));

[
 {width: {max: 0}},
 {height: {max: 0}},
 {frameRate: {max: 0}},
 {width: {max: -1}},
 {height: {max: -1}},
 {frameRate: {max: -1}},
 {width: {min: 100, max: 10}},
 {height: {min: 100, max: 10}},
 {frameRate: {min: 100, max: 10}},
].forEach(constraints => promise_test(async t => {
  const stream = await getDisplayMedia();
  t.add_cleanup(() => stopTracks(stream));
  const [track] = stream.getTracks();
  try {
    await track.applyConstraints(constraints);
  } catch (err) {
    assert_equals(err.name, 'OverconstrainedError', err.message);
    assert_equals(err.constraint, Object.keys(constraints)[0], "Constraint is set");
    return;
  }
  assert_unreached('applyConstraints hould have failed');
}, `applyConstraints(${j(constraints)}) for display media 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');

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

{
  const properties = ["displaySurface"];
  properties.forEach((property) => {
    test(() => {
      const supportedConstraints =
        navigator.mediaDevices.getSupportedConstraints();
      assert_true(supportedConstraints[property]);
    }, property + " is supported");
  });
}

[
 {video: {displaySurface: "monitor"}},
 {video: {displaySurface: "window"}},
 {video: {displaySurface: "browser"}},
 {selfBrowserSurface: "include"},
 {selfBrowserSurface: "exclude"},
 {surfaceSwitching: "include"},
 {surfaceSwitching: "exclude"},
 {systemAudio: "include"},
 {systemAudio: "exclude"},
 {windowAudio: "exclude"},
 {windowAudio: "window"},
 {windowAudio: "system"},
].forEach(constraints => promise_test(async t => {
  const stream = await getDisplayMedia(constraints);
  t.add_cleanup(() => stopTracks(stream));
}, `getDisplayMedia(${j(constraints)}) must succeed`));

[
 {selfBrowserSurface: "invalid"},
 {surfaceSwitching: "invalid"},
 {systemAudio: "invalid"},
 {windowAudio: "invalid"},
 {monitorTypeSurfaces: "invalid"},
].forEach(constraints => promise_test(async t => {
  await test_driver.bless('getDisplayMedia()');
  const p = navigator.mediaDevices.getDisplayMedia(constraints);
  t.add_cleanup(async () => {
    try { stopTracks(await p) } catch {}
  });
  await promise_rejects_js(
    t, TypeError, Promise.race([p, Promise.resolve()]),
    'getDisplayMedia should have returned an already-rejected promise.');
}, `getDisplayMedia(${j(constraints)}) must fail with TypeError`));

test(() => {
  const supportedConstraints =
    navigator.mediaDevices.getSupportedConstraints();
  assert_true(supportedConstraints.suppressLocalAudioPlayback);
}, "suppressLocalAudioPlayback is supported");

{
  const suppressLocalAudioPlaybacks = [true, false];
  suppressLocalAudioPlaybacks.forEach((suppressLocalAudioPlayback) => {
    promise_test(async (t) => {
      const stream = await getDisplayMedia({
        audio: { suppressLocalAudioPlayback },
      });
      t.add_cleanup(() => stopTracks(stream));
      const [videoTrack] = stream.getVideoTracks();
      assert_false("suppressLocalAudioPlayback" in videoTrack.getSettings());
      const [audioTrack] = stream.getAudioTracks();
      const audioTrackSettings = audioTrack.getSettings();
      assert_true("suppressLocalAudioPlayback" in audioTrackSettings);
      assert_equals(
        audioTrackSettings.suppressLocalAudioPlayback,
        suppressLocalAudioPlayback
      );
      await audioTrack.applyConstraints();
      assert_true("suppressLocalAudioPlayback" in audioTrackSettings);
      assert_equals(
        audioTrackSettings.suppressLocalAudioPlayback,
        suppressLocalAudioPlayback
      );
    }, `getDisplayMedia({"audio":{"suppressLocalAudioPlayback":${suppressLocalAudioPlayback}}}) with getSettings`);
  });
}

promise_test(async t => {
  const stream = await getDisplayMedia({video: true});
  t.add_cleanup(() => stopTracks(stream));
  const capabilities = stream.getVideoTracks()[0].getCapabilities();
  assert_any(
      assert_equals, capabilities.displaySurface,
      ['monitor', 'window', 'browser']);
}, 'getDisplayMedia() with getCapabilities');

promise_test(async (t) => {
  const constraints = {
    video: { displaySurface: "monitor" },
    monitorTypeSurfaces: "exclude",
  };
  await test_driver.bless('getDisplayMedia()');
  const p = navigator.mediaDevices.getDisplayMedia(constraints);
  t.add_cleanup(async () => {
    try { stopTracks(await p) } catch {}
  });
  await promise_rejects_js(
    t, TypeError, Promise.race([p, Promise.resolve()]),
    'getDisplayMedia should have returned an already-rejected promise.');
  }, `getDisplayMedia({"video":{"displaySurface":"monitor"},"monitorTypeSurfaces":"exclude"}) rejects with TypeError`);

promise_test(async (t) => {
  const stream = await getDisplayMedia({
    video: { displaySurface: "monitor" },
    monitorTypeSurfaces: "include",
  });
  t.add_cleanup(() => stopTracks(stream));
  const { displaySurface } = stream.getTracks()[0].getSettings();
  assert_equals(displaySurface, "monitor");
}, `getDisplayMedia({"video":{"displaySurface":"monitor"},"monitorTypeSurfaces":"include"}) resolves with a monitor track`);

promise_test(async (t) => {
  const stream = await getDisplayMedia({
    monitorTypeSurfaces: "exclude",
  });
  t.add_cleanup(() => stopTracks(stream));
  const { displaySurface } = stream.getTracks()[0].getSettings();
  assert_any(assert_equals, displaySurface, ["window", "browser"]);
}, `getDisplayMedia({"monitorTypeSurfaces":"exclude"}) resolves with a non monitor track`);

</script>
