chromium/third_party/blink/web_tests/media/autoplay/document-user-activation.html

<!DOCTYPE html>
<title>Test document user gesture autoplay policy</title>
<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>
<body>
  <div id='target'>target</div>
</body>
<script>
promise_test(t => {
  t.add_cleanup(() => {
    internals.settings.setAutoplayPolicy('no-user-gesture-required');
  });

  internals.settings.setAutoplayPolicy('document-user-activation-required');

  var video = document.createElement('video');
  video.src = '../content/test.ogv';
  return promise_rejects_dom(t, 'NotAllowedError', video.play());
}, 'Not allowed to autoplay without some sort of user gesture');

promise_test(t => {
  t.add_cleanup(() => {
    internals.settings.setAutoplayPolicy('no-user-gesture-required');
  });

  internals.settings.setAutoplayPolicy('document-user-activation-required');
  document.querySelector('#target').focus();
  eventSender.keyDown('a');

  var video = document.createElement('video');
  video.src = '../content/test.ogv';
  return video.play();
}, 'Allowed to autoplay if the document received a key event');

promise_test(t => {
  t.add_cleanup(() => {
    internals.settings.setAutoplayPolicy('no-user-gesture-required');
  });

  internals.settings.setAutoplayPolicy('document-user-activation-required');
  var bounds = document.querySelector('#target').getBoundingClientRect();
  var x = bounds.left + bounds.width / 2;
  var y = bounds.top + bounds.height / 2;
  chrome.gpuBenchmarking.pointerActionSequence([{
    'source': 'mouse',
    'actions': [
      { 'name': 'pointerDown', 'x': x, 'y': y },
      { 'name': 'pointerUp' },
    ],
  }]);

  var video = document.createElement('video');
  video.src = '../content/test.ogv';
  return video.play();
}, 'Allowed to autoplay if the document received a click');

// TODO(mlamouri): should not be allowed to autoplay if the document only
// received a mouse down or up.

// TODO(mlamouri): should not be allowed to autoplay if the document only
// received a mouse wheel event.

promise_test(t => {
  t.add_cleanup(() => {
    internals.settings.setAutoplayPolicy('no-user-gesture-required');
  });

  internals.settings.setAutoplayPolicy('document-user-activation-required');
  var bounds = document.querySelector('#target').getBoundingClientRect();
  var x = bounds.left + bounds.width / 2;
  var y = bounds.top + bounds.height / 2;
  chrome.gpuBenchmarking.pointerActionSequence([{
    'source': 'touch',
    'actions': [
      { 'name': 'pointerDown', 'x': x, 'y': y },
      { 'name': 'pointerUp' },
    ],
  }]);

  var video = document.createElement('video');
  video.src = '../content/test.ogv';
  return video.play();
}, 'Allowed to autoplay if the document received a tap');

// TODO(mlamouri): should not allowed to autoplay if the document only received
// a tap down or up.

// TODO(mlamouri): should not allowed to autoplay if the document was scrolled
// with touch events.

promise_test(async t => {
  t.add_cleanup(() => {
    internals.settings.setAutoplayPolicy('no-user-gesture-required');
  });

  internals.settings.setAutoplayPolicy('document-user-activation-required');
  var bounds = document.querySelector('#target').getBoundingClientRect();
  var x = bounds.left + bounds.width / 2;
  var y = bounds.top + bounds.height / 2;
  chrome.gpuBenchmarking.pointerActionSequence([{
    'source': 'touch',
    'actions': [
      { 'name': 'pointerDown', 'x': x, 'y': y },
      { 'name': 'pointerUp' },
    ],
  }]);


  var video =
      document.implementation.createHTMLDocument().createElement('video');
  video.src = '../content/test.ogv';
  document.body.appendChild(video);  // Moved to `window.document`.
  document.body.removeChild(video);  // To avoid polluting the DOM.

  await new Promise(resolve => {
    video.addEventListener('volumechange', resolve, { once: true });

    video.volume = 0.5;
  });

  return video.play();
}, 'After being moved to a document with user gesture, autoplay is allowed');

promise_test(t => {
  t.add_cleanup(() => {
    internals.settings.setAutoplayPolicy('no-user-gesture-required');
    document.body.removeChild(document.querySelector('iframe'));
  });

  internals.settings.setAutoplayPolicy('document-user-activation-required');

  var iframe = document.createElement('iframe');
  return new Promise((resolve, reject) => {
    iframe.addEventListener('load', () => {
      var bounds = document.querySelector('iframe').getBoundingClientRect();
      var x = bounds.left + bounds.width / 2;
      var y = bounds.top + bounds.height / 2;
      chrome.gpuBenchmarking.pointerActionSequence([{
        'source': 'touch',
        'actions': [
          { 'name': 'pointerDown', 'x': x, 'y': y },
          { 'name': 'pointerUp' },
        ],
      }]);

      var video = document.createElement('video');
      video.src = '../content/test.ogv';
      video.play().then(resolve, reject);
    });

    iframe.src = 'resources/document-user-activation-iframe.html';
    document.body.appendChild(iframe);
  });
}, 'Main frame allowed to play if iframe received a gesture');

promise_test(t => {
  t.add_cleanup(() => {
    internals.settings.setAutoplayPolicy('no-user-gesture-required');
    document.body.removeChild(document.querySelector('iframe'));
  });

  internals.settings.setAutoplayPolicy('document-user-activation-required');

  var iframe = document.createElement('iframe');
  return new Promise((resolve, reject) => {
    iframe.addEventListener('load', () => {
      var bounds = document.querySelector('iframe').getBoundingClientRect();
      var x = bounds.left + bounds.width / 2;
      var y = bounds.top + bounds.height / 2;
      // TODO(mlamouri): for some reasons, using pointerActanionSequence fails.
      eventSender.gestureTap(x, y);

      window.addEventListener('message', e => {
        e.data.result ? resolve() : reject();
      });

      iframe.contentWindow.postMessage({
        command: 'play'
      }, '*');
    });

    iframe.src = 'resources/document-user-activation-iframe.html';
    document.body.appendChild(iframe);
  });
}, 'iframe allowed to play if it received a gesture');

promise_test(async t => {
  t.add_cleanup(() => {
    internals.settings.setAutoplayPolicy('no-user-gesture-required');
  });

  internals.settings.setAutoplayPolicy('document-user-activation-required');

  var video = document.createElement('video');
  video.src = '../content/test.ogv';

  await test_driver.bless('open PiP window');
  const pipWindow = await documentPictureInPicture.requestWindow();
  pipWindow.document.body.append(video);

  await test_driver.bless('play PiP video from opener');
  return video.play();
}, 'Allowed to autoplay if the document opener was blessed');

</script>