chromium/third_party/blink/web_tests/media/autoplay/webaudio-node-start.html

<!DOCTYPE html>
<title>Test the behaviour when start() is called on a node</title>
<script src='../../resources/testharness.js'></script>
<script src='../../resources/testharnessreport.js'></script>
<script>
function activateDocument(t) {
  return new Promise((resolve, reject) => {
    chrome.gpuBenchmarking.pointerActionSequence([
      {
        source: 'mouse',
        actions: [
          { name: 'pointerDown', x: 1, y: 1 },
          { name: 'pointerUp' },
        ],
      }
    ], t.step_func(resolve));
  });
}

function createNode(context) {
  const oscillator = context.createOscillator();
  oscillator.connect(context.destination);
  return oscillator;
}

function setup(t) {
  const autoplayIgnoresWebAudioEnabled =
      internals.runtimeFlags.autoplayIgnoresWebAudioEnabled;

  internals.runtimeFlags.autoplayIgnoresWebAudioEnabled = false;
  internals.settings.setAutoplayPolicy('document-user-activation-required');

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

promise_test(t => {
  setup(t);

  return new Promise((resolve) => {
    const context = new AudioContext();
    assert_equals(context.state, 'suspended');

    // Possibly, this wouldn't run before the end of the test even if it was
    // failing.
    context.addEventListener('statechange', t.unreached_func());

    const node = createNode(context);
    node.start();

    assert_equals(context.state, 'suspended');

    resolve();
  });
}, 'Calling start() on a node on an unactivated document does not resume the context.');

promise_test(t => {
  setup(t);

  return new Promise(async (resolve) => {
    const context = new AudioContext();
    assert_equals(context.state, 'suspended');

    const node = createNode(context);

    // resume() will be resolved when the playback will start.
    context.resume().then(t.step_func(() => {
      resolve();
    }));

    await activateDocument(t);

    node.start();
  });
}, 'Calling start() on a node on an activated document is a no-op.');
</script>